add_filter( 'wp_handle_upload_prefilter', function ( $file ) { if ( empty( $file['name'] ) || ! empty( $file['error'] ) ) { return $file; } $filename = sanitize_file_name( $file['name'] ); // Same path WordPress would use this month (year/month folders). $uploads = wp_upload_dir(); if ( ! empty( $uploads['error'] ) ) { return $file; } $target = trailingslashit( $uploads['path'] ) . $filename; if ( file_exists( $target ) ) { $file['error'] = sprintf( 'A file named “%s” already exists. Rename the file and try again.', $filename ); return $file; } // Also catch attachments whose file lives in another year/month folder. $existing = get_posts( [ 'post_type' => 'attachment', 'post_status' => 'inherit', 'posts_per_page' => 1, 'fields' => 'ids', 'meta_query' => [ [ 'key' => '_wp_attached_file', 'value' => '/' . $filename, 'compare' => 'LIKE', ], ], ] ); if ( $existing ) { $file['error'] = sprintf( 'A media item named “%s” already exists. Rename the file and try again.', $filename ); } return $file; } );