@aihellolabs/google-shopping-feed-validator
v0.1.1
Published
Free Google Shopping feed validator CLI. Check Google Merchant Center product feeds for missing attributes, invalid prices, duplicate IDs, GTIN errors, and CSV or TSV formatting issues.
Maintainers
Readme
Google Shopping Feed Validator
Free, open-source command-line tool to validate Google Merchant Center product feeds before uploading them to Google Shopping.
Built by AiHello
Release status: this checkout prepares CLI version 0.1.1, a documentation and metadata update. Version 0.1.0 already exists on npm and cannot be overwritten. The npm version badge follows the published registry tag and may lag a release; it does not identify the local checkout version. Download statistics are currently unavailable, and the private GitHub workflow cannot expose a public build-status badge. The availability badges above show those states; the CI badge links to the real workflow for authorized users. No download counts or passing-build status are invented.
Why use this CLI?
Find product feed problems before a catalog upload or an automated export reaches Google Merchant Center:
- Missing mandatory product attributes, including supported plain or structured title/description fields.
- Incorrect price, currency, sale-price or availability formatting.
- Duplicate product identifiers and inconsistent variant groups.
- Invalid GTIN lengths or check digits, without changing leading zeros.
- Malformed CSV/TSV, duplicate headers, unknown columns and empty product records.
- Product feed quality diagnostics with source rows, recommendations and specification links.
google-feed-lint runs locally without an account, API key, signup, telemetry or paid service. It never uploads a feed or changes the original file. CSV, TSV/TXT and named gzip files are supported; XML/RSS/Atom is not supported. A successful result does not guarantee Merchant Center approval. This independent utility is not an official Google product.
Installation
Requires Node.js 22 or newer and npm. Install the latest published release:
npm install -g @aihellolabs/google-shopping-feed-validator
google-feed-lint --helpRun without a global installation:
npx @aihellolabs/google-shopping-feed-validator --helpThese registry commands currently install version 0.1.0. Version 0.1.1 will become available only after its owner publishes it. To use this checkout before that publication, authorized repository collaborators can build the source:
git clone https://github.com/aihellolabs/google-shopping-feed-validator.git
cd google-shopping-feed-validator
npm ci
npm run build
node dist/cli.js --help
node dist/cli.js --versionThe executable is google-feed-lint, compiled to dist/cli.js. In the commands below, a source-checkout user can replace google-feed-lint with node dist/cli.js. Reference documents and examples also ship in the npm tarball. GitHub source links require access while the repository remains private.
Quick start
Save this complete synthetic feed as valid.csv:
id,title,description,link,image_link,availability,price,identifier_exists,google_product_category
cup-blue,Blue cup,Hand-glazed ceramic cup.,https://example.com/cup,https://example.com/cup.jpg,in_stock,24.95 USD,no,Home & Garden > Kitchen & Dining > Tableware > DrinkwareValidate the local feed with explicit target context:
google-feed-lint valid.csv --country US --language enExact stdout from CLI 0.1.1; exit code 0:
PASS valid.csv: 1 products, 0 errors, 0 warnings
Offline lint does not guarantee Google approval.The illustrative URLs are not fetched. identifier_exists=no describes this sample item without assigned identifiers; it is not a way to suppress real identifiers on a merchant's products.
Write a JSON report to a new file:
google-feed-lint valid.csv --country US --language en --format json --out report.jsonThe same JSON report appears on stdout. Existing paths are refused. A .json output filename alone does not select JSON; include --format json.
Read uncompressed CSV from stdin:
cat valid.csv | google-feed-lint - --delimiter csv --country US --language en --format jsonUse --strict when warnings should also fail validation. Optional --check-urls enables HTTPS reachability checks for your own real product URLs; it is not needed for these offline examples.
Features
All data rules below apply to parsed CSV/TSV/TXT records, including files decompressed from a .gz filename. Diagnostics preserve source coordinates.
| Validation category | Implemented checks | Resulting diagnostics |
| ------------------------ | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| File format and encoding | UTF-8, BOM/CRLF, quoted commas/newlines, escaped quotes, malformed records, empty input | Syntax findings; unsupported encoding or resource failures exit 2 |
| Headers | Friendly, bracketed and Google-style aliases; repeated supported attributes; unknown or conflicting columns | Errors for invalid layouts; warnings for unknown headers |
| Required attributes | ID, link, primary image, availability, price, and plain or structured title/description | Missing-column or missing-value errors |
| Product identifiers | Duplicate IDs, ID length, identity whitespace/case review | Errors for duplicate/invalid IDs; warnings for reviewable identity values |
| Product text | Supported structured layouts and title/description lengths | Layout errors; text-length and competing-form warnings |
| Prices and currencies | Currency-coded decimal amounts, sale-price relationships, matching currencies, sale intervals | Format/relationship errors; precision, zero-price and mixed-currency warnings |
| Availability | Supported values, preorder/backorder dates and real calendar values | Invalid-value/date errors; temporal review warnings |
| GTIN, brand and MPN | GTIN widths/check digits, identifier-exists consistency and contextual identifier dependencies | Invalid supplied GTIN errors; contextual brand/MPN and missing-identifier warnings |
| Variants | Item groups, explicit option layouts/dimensions, duplicate selections and sibling consistency | Errors for contradictory explicit options; warnings for ambiguous standard-attribute combinations |
| Apparel context | Selected product-category and country/destination-dependent color, size, age-group and gender rules | Conditional errors or recommendations based on supplied context |
| URLs | Offline HTTP(S) syntax for link, image_link, mobile_link; opt-in bounded HTTPS checks | Syntax errors; reachability warnings that fail only with --strict |
| Reporting | Text/JSON, source rows, stable rule IDs, recommendations, strict mode and exclusive report creation | Deterministic findings and documented exit codes |
Supported input and resource limits
- CSV, tab-delimited TSV/TXT and files with a
.gzsuffix; gzip detection is filename-based. Stdin accepts uncompressed text. JSON/JSONL, XML, RSS and Atom are unsupported. --delimiter csv|tsvoverrides extension/content inference. Google upload restrictions on embedded tabs/newlines still apply to TSV, even when locally parsed.- Repeated
gtin,additional_image_linkandvariant_optioncolumns are merged only for supported layouts. Other conflicting/duplicate headers produce errors. - 20 MiB encoded/decompressed input, 100,000 product rows, 512 columns, 65,536 UTF-16 code units per field, 1,024 decimal digits per money amount and 10,000 findings. Exceeding a diagnostic limit produces an explicit error. Records remain in bounded memory; split larger catalogs.
- No automatic feed repair, conversion or upload.
--outwrites a report, never a modified product feed.
CLI reference
The following is the actual output of google-feed-lint --help in version 0.1.1:
google-feed-lint 0.1.1
Lint Google Merchant Center product CSV/TSV files locally.
Usage: google-feed-lint <file.csv|file.tsv|file.txt|file.csv.gz|-> [options]
--country US Target ISO country for conditional rules
--language en Target BCP 47 language tag
--destination shopping shopping or free-listings
--delimiter csv csv or tsv (otherwise inferred from file/content)
--format text text or json
--out report.json Write report to a NEW file; never overwrite
--strict Warnings also produce exit 1
--check-urls Explicitly enable bounded HTTPS URL checks
--max-concurrency 5 URL check workers (1-10)
--timeout-ms 5000 Per-URL deadline including redirects (1-60000)
--help Show help
--version Show version
Examples:
google-feed-lint products.csv --country US --language en
google-feed-lint feed.tsv --format json --out report.json
google-feed-lint products.csv --check-urls --max-concurrency 5
cat feed.tsv | google-feed-lint - --delimiter tsv --format json
Exit codes: 0 pass, 1 validation failure, 2 usage/I/O/runtime failure.
Offline by default. No Google approval guarantee. XML is not supported.Exactly one input path or - is required for validation. --help and --version work without a file and also honor --format json. There are no short aliases such as -h, -v, -f or -o.
Defaults are shopping, inferred delimiter, text output, no report file, non-strict offline validation, five URL-check workers and a 5,000 ms per-URL deadline. Country and language are unspecified until provided. Country is an ISO 3166-1 alpha-2 code; language is a well-formed BCP 47 tag, not a check that the text actually uses that language.
| Exit code | Meaning |
| --------- | ------------------------------------------------------------------------------------------- |
| 0 | No errors; with --strict, no warnings either |
| 1 | Feed validation failed, including malformed delimited input; strict-mode warnings also fail |
| 2 | Invalid usage, I/O, encoding, resource-limit or runtime failure |
Errors identify definite problems in the implemented rules. Warnings identify recommendations, incomplete context or values requiring review. Informational findings do not fail validation. JSON mode writes a single parseable JSON document to stdout, including usage/I/O errors. Text usage errors go to stderr. A new report file is required on every run with --out.
Optional URL checking
--check-urls explicitly enables network access; otherwise no product URLs are requested. Checks skip HTTP, reject credentials, nonpublic IPs and nonstandard ports, pin validated DNS answers and recheck redirects. Limits are three redirects, a 1 MiB byte budget per URL check across its redirect chain by default, up to 10,000 URL references, and the configured worker/deadline bounds. The API can set that byte budget up to 10 MiB. No scripts, image metadata or page content are evaluated.
additional_image_link is parsed/merged and can be included in optional network checking, but it does not receive the offline syntax checks applied to link, image_link and mobile_link. A failed reachability check means this tool could not verify a URL; it does not establish Google's decision.
Example validation results
The valid valid.csv feed in Quick start exits 0 with zero findings. The following independent inputs were run through CLI 0.1.1 with the commands shown. All URLs are synthetic, and no network checks are used. Each invalid input exits 1, with exactly one error and zero warnings.
Missing required title
The title is empty and no structured alternative is supplied. Save as missing-title.csv:
id,title,description,link,image_link,availability,price,identifier_exists,google_product_category
cup-blue,,Hand-glazed ceramic cup.,https://example.com/cup,https://example.com/cup.jpg,in_stock,24.95 USD,no,Home & Garden > Kitchen & Dining > Tableware > Drinkwaregoogle-feed-lint missing-title.csv --country US --language enExact stdout; exit code 1:
FAIL missing-title.csv: 1 products, 1 errors, 0 warnings
ERROR required.value row 2 title: A nonempty title or valid structured_title is required.
Supply title or its structured alternative.
Offline lint does not guarantee Google approval.Missing required image
The primary image URL is empty. Save as missing-required-field.csv:
id,title,description,link,image_link,availability,price,identifier_exists,google_product_category
cup-blue,Blue cup,Hand-glazed ceramic cup.,https://example.com/cup,,in_stock,24.95 USD,no,Home & Garden > Kitchen & Dining > Tableware > Drinkwaregoogle-feed-lint missing-required-field.csv --country US --language enExact stdout; exit code 1:
FAIL missing-required-field.csv: 1 products, 1 errors, 0 warnings
ERROR required.value row 2 image_link: image_link must not be empty.
Supply a nonempty image_link value.
Offline lint does not guarantee Google approval.Invalid price
The price omits its currency code. Save as invalid-price.csv:
id,title,description,link,image_link,availability,price,identifier_exists,google_product_category
cup-blue,Blue cup,Hand-glazed ceramic cup.,https://example.com/cup,https://example.com/cup.jpg,in_stock,24.95,no,Home & Garden > Kitchen & Dining > Tableware > Drinkwaregoogle-feed-lint invalid-price.csv --country US --language enExact stdout; exit code 1:
FAIL invalid-price.csv: 1 products, 1 errors, 0 warnings
ERROR price.format row 2 price: Expected a nonnegative decimal amount followed by an ISO 4217 currency code.
Use a value such as 29.95 USD, without currency symbols or thousands separators.
Offline lint does not guarantee Google approval.Duplicate product identifiers
Two product rows reuse the same ID. Save as duplicate-ids.csv:
id,title,description,link,image_link,availability,price,identifier_exists,google_product_category
cup-blue,Blue cup,Hand-glazed ceramic cup.,https://example.com/cup,https://example.com/cup.jpg,in_stock,24.95 USD,no,Home & Garden > Kitchen & Dining > Tableware > Drinkware
cup-blue,Second cup,Hand-glazed ceramic cup.,https://example.com/cup,https://example.com/cup.jpg,in_stock,24.95 USD,no,Home & Garden > Kitchen & Dining > Tableware > Drinkwaregoogle-feed-lint duplicate-ids.csv --country US --language enExact stdout; exit code 1:
FAIL duplicate-ids.csv: 2 products, 1 errors, 0 warnings
ERROR id.duplicate row 3 id: This product ID already occurs at row 2.
Use a different ID for each distinct offer within the same country and language.
Offline lint does not guarantee Google approval.GTIN checksum error
The supplied 12-digit GTIN has an incorrect final check digit. This sample uses identifier_exists=yes; a checksum example does not establish identifier ownership. Save as invalid-gtin.csv:
id,title,description,link,image_link,availability,price,identifier_exists,google_product_category,gtin
cup-blue,Blue cup,Hand-glazed ceramic cup.,https://example.com/cup,https://example.com/cup.jpg,in_stock,24.95 USD,yes,Home & Garden > Kitchen & Dining > Tableware > Drinkware,036000291453google-feed-lint invalid-gtin.csv --country US --language enExact stdout; exit code 1:
FAIL invalid-gtin.csv: 1 products, 1 errors, 0 warnings
ERROR gtin.check_digit row 2 gtin: The GTIN check digit does not match its preceding digits.
Verify the identifier against its packaging or manufacturer; do not guess a replacement.
Offline lint does not guarantee Google approval.JSON output
google-feed-lint valid.csv --country US --language en --format jsonCaptured response excerpt; only the limitations array is omitted:
{
"schemaVersion": "1.0",
"tool": "google-shopping-feed-validator",
"version": "0.1.1",
"file": "valid.csv",
"context": {
"destination": "shopping",
"country": "US",
"language": "en"
},
"rows": 1,
"valid": true,
"summary": {
"errors": 0,
"warnings": 0,
"info": 0
},
"findings": []
}For a failed validation, the JSON findings array contains ruleId, severity, message, file, row or location, field, recommendation, and optional actualValue/documentationUrl. Values are bounded and sensitive URL components are redacted. Findings are ordered deterministically by row, field and rule ID. See the complete report schema, also included as docs/report.schema.json in the package.
Google Merchant Center compatibility
The implemented rules were reviewed against Google's documentation on 2026-10-22. They are a dated subset, not a complete implementation of every feed method or country/category requirement. Consult the official Google Merchant Center product data specification.
Supported checks cover the core fields, structured title/description alternatives, price/sale-price consistency, supported availability and dates, supplied GTIN checksums, item-group/variant consistency and selected country/destination-dependent apparel rules. Provide --country, --language and --destination for relevant context. Missing context cannot establish a conditional requirement. Brand, GTIN, condition and shipping are not treated as universally required fields.
CSV is a useful local lint input; Google's text-file upload guidance specifies tab-delimited files. A passing CSV result does not mean that CSV is accepted by every Merchant Center upload method. See Google's product-file guidance and tab-delimited format guidance.
Known optional headers can be recognized without their full semantics being validated. This CLI does not exhaustively verify shipping/tax, product safety, legal disclosures, loyalty or subscription programs, certification, energy labels, complete taxonomy coverage, landing-page consistency, domain ownership, account settings, Google policies or GTIN assignment. It does not inspect image content or dimensions. Merchant Center settings can supply some information absent from a feed.
A pass is an offline diagnostic result, not approval, certification or an eligibility guarantee. Review errors and warnings before uploading. Maintainers should update the supported rules and synthetic fixtures when official specifications change.
CI/CD integration
This example validates a checked-in feed inside this validator's source repository. It works without installing a published package and uses the same checkout/setup actions as the existing CI workflow:
name: Validate product feed
on: [push, pull_request]
permissions:
contents: read
jobs:
validate-feed:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
- run: >
node dist/cli.js examples/valid.csv
--country US --language en --strict
--format json --out feed-report.jsonReplace examples/valid.csv with your checked-in feed. Exit 1 fails the step for validation errors or strict-mode warnings; exit 2 fails it for usage/runtime problems. The JSON appears in the job log and a new feed-report.json file. This is a suggested integration, not a newly installed workflow. Another private repository needs an authorized checkout of this source, or can install a published CLI release. The separate owner-triggered publishing workflow is documented in the release guide; this feed-validation example does not publish.
Programmatic usage
The package exposes a supported ESM API with TypeScript declarations. Add the published package to a Node.js project:
npm install @aihellolabs/google-shopping-feed-validatorReuse valid.csv from Quick start and save this as validate.mjs:
import { readFileSync } from 'node:fs';
import { lintFile, lintText } from '@aihellolabs/google-shopping-feed-validator';
const options = { country: 'US', language: 'en', strict: true };
const fromFile = await lintFile('valid.csv', options);
const fromText = lintText(readFileSync('valid.csv', 'utf8'), {
...options,
file: 'valid.csv',
});
console.log(fromFile.valid); // true
console.log(fromText.summary); // { errors: 0, warnings: 0, info: 0 }node validate.mjsBoth functions include parser and domain findings. lintText is synchronous and offline. lintFile only requests URLs with checkUrls: true; it never writes a report file. The API also exports lintFeed, parseFeed, readFeed, validateFeed, formatReport, InputError, VERSION, resource limits and types. Low-level validateFeed returns domain findings; preserve parser findings when using it directly. Pass now: new Date(...) for reproducible date-sensitive validation.
Built by AiHello
This open-source tool is developed and maintained by AiHello, an ecommerce advertising automation platform helping Amazon sellers and brands improve advertising performance.
AiHello provides Amazon PPC automation, advertising analytics, bid optimization, campaign management, and performance optimization.
Learn more: https://www.aihello.com
licensing
The distribution contains compiled JavaScript, declarations, README, license, changelog, security notes, reference docs and synthetic examples. Runtime dependencies csv-parse and ipaddr.js are MIT licensed; dependency versions are locked. Read the security notes. This project is licensed under MIT, copyright 2026 AiHello Labs.
