この記事は現在、英語でのみご利用いただけます。

WebPDec 12, 20258 min read

A Developer's Guide to WebP Conversion Logs

WebP conversion logs are more than progress messages. They tell developers whether a job processed the expected files, which outputs were written, which inputs failed, and whether the result is safe to hand to reviewers. In local workflows, logs help with debugging. In CI, they become the audit trail for image automation.

The key is to separate human-readable progress from machine-readable reporting. Both can be useful, but they serve different jobs.

"Check the logs for errors" is too imprecise for developer work. A log review has to name the command, preserve the structured output, classify every failed or skipped file, and keep mechanical success separate from visual approval.

Start With the Command#

Every log should be interpreted in relation to the command that produced it. Record the input path, output path, format, quality setting, and important flags.

npx -y getwebp ./public/images \
  -o ./dist/images \
  --recursive \
  --quality 82 \
  --format webp \
  --json > conversion.ndjson

Without the command, a log line such as "converted hero.jpg" is incomplete. You do not know which settings were used or where the output was written.

For team workflows, save the approved command in documentation or a script so logs can be compared across runs. The GetWebP CLI command reference documents the relevant flags: --output, --recursive, --quality, --format, --skip-existing, and --json. It also matters that the CLI writes converted files to the output path and does not modify or delete the original files.

Record these command facts next to the report:

ItemWhy it matters
Input pathProves which source folder or file was processed
Output pathLets reviewers find the exact generated files
FormatSeparates WebP and AVIF runs
Quality modeExplains whether quality was fixed or auto-selected
Recursive flagPrevents confusion when subdirectories are missing
Skip-existing flagExplains why unchanged outputs may appear as skipped
CLI versionHelps compare reports when tooling changes

Read the Exit Code First#

The process exit code gives the overall status. For GetWebP CLI, the LLM context document lists the current exit-code model:

CodeMeaningDeveloper response
0SuccessParse the report and continue to visual review
1Generic errorCheck stderr or the JSON error message
2Usage errorFix the command arguments before retrying
3Partial failureParse per-file results and decide whether partial output is usable
4Auth errorRe-activate or fix the license state before retrying
5Network errorRetry with backoff if the job depends on online services
6Free limit reachedTreat the run as truncated and process the remainder
75License revoked mid-sessionStop automation and refresh the license state
76Disk fullFree space before rerunning
130InterruptedTreat the run as incomplete
143TerminatedTreat the run as incomplete

The exit code answers the first question: did the job complete successfully enough for the next step?

The detailed log answers the second question: what happened to each file?

Do not rely only on the last visible console line. CI logs can be truncated, and long parallel jobs may interleave output. Capture structured output when the result matters.

Prefer Structured Output for Automation#

When a script or CI job needs to react to conversion results, use NDJSON output:

npx -y getwebp ./public/images -o ./dist/images --json > conversion.ndjson

The JSON output reference is specific: --json emits newline-delimited JSON, not one large JSON array. Each line is a complete envelope with @timestamp, @level, @message, @module, type, and data. Human messages go to stderr, so stdout can be captured safely.

The first line is always a version preamble. The conversion result then appears as one of these event types:

Event typeWhat it means
convert.completedThe conversion run returned per-file results
convert.truncatedThe Free plan file limit was reached and remaining files were skipped
convert.failedThe command could not start or failed at the command level

Do not parse the file as a single JSON object. Filter by type:

jq -r 'select(.type == "convert.completed") | .data.results[] | [.status, .file, (.outputPath // ""), (.error // "")] | @tsv' conversion.ndjson

Structured output can be parsed for:

  • failed files
  • skipped files
  • output paths
  • per-file error messages
  • originalSize, newSize, and savedRatio
  • the human-friendly saved percentage string
  • quality and qualityMode
  • successCount and failedCount
  • truncated Free-plan runs

This is more reliable than regular expressions over console text.

Read Results as Records, Not Sentences#

For a successful file, a results[] record includes the source file, output path, original size, new size, savings ratio, quality, quality mode, and status: "success".

{
  "file": "photos/hero.jpg",
  "outputPath": "/abs/photos/hero.webp",
  "originalSize": 204800,
  "newSize": 133120,
  "savedRatio": 0.35,
  "saved": "35.0%",
  "quality": 82,
  "qualityMode": "auto",
  "status": "success"
}

Use originalSize and newSize when you need exact byte math. Use savedRatio for relative comparison, including the edge case where output is larger than the original and the ratio is negative. Use saved only as a display value.

For an errored file, the record is intentionally smaller:

{
  "file": "corrupt.png",
  "status": "error",
  "error": "Decode failed: Invalid PNG header"
}

That shape works for triage, but it cannot support quality approval. No output path means there is no converted file to review.

Look for Skipped Files#

Skipped files are not always errors. In the per-file result schema, status: "skipped" is used for --skip-existing style cases where the output already exists. A Free-plan limit is reported at the event level as convert.truncated, with processed, skipped, limit, and upgrade_url in the event data.

Still, skipped files need interpretation. If a source image changed but the existing output was skipped, the published output may be stale. If many files are skipped unexpectedly, the input path or flags may be wrong.

A good review asks: were these files supposed to be skipped?

Add a short decision next to each skip group:

Skip patternReview decision
Existing output and unchanged sourceAccept and keep the row as an intentional skip
Existing output but source changedDelete or regenerate the output before release
Free-plan truncationSplit the run, upgrade, or document the unprocessed remainder
Unsupported source type in the folderMove it to a separate workflow instead of retrying blindly

Treat Per-File Errors as Action Items#

Per-file errors should produce a short triage list:

product-17.png: corrupt input
team-photo.jpg: permission denied
diagram.svg: unsupported format for this workflow

Each category has a different fix. Corrupt inputs need replacement. Permission errors need file-system changes. Unsupported formats need a format decision, not repeated retries.

If a batch has many failures with the same cause, fix the shared cause before rerunning.

For CI, make the action explicit:

errors=$(jq -r 'select(.type == "convert.completed") | .data.results[] | select(.status == "error") | .file' conversion.ndjson)
if [ -n "$errors" ]; then
  echo "$errors"
  exit 3
fi

That example treats per-file errors as a failing gate. Some teams choose a softer gate for editorial branches and a hard gate for release branches. The important part is that the policy is visible and tied to the structured result, not to a fragile grep over console text.

Connect Logs to Visual Review#

A clean log does not approve visual quality. It only proves the mechanical process completed. The next step is to review outputs in context.

Use logs to choose review samples:

  • largest outputs
  • files with low savings
  • files converted from screenshots
  • files converted from transparent PNGs
  • files in high-value templates

This makes visual review more focused than randomly opening outputs.

The log can tell you which files deserve attention, but it cannot tell you whether a product texture, screenshot label, portrait, or transparent logo still looks acceptable. Add a second column outside the conversion report:

Log resultHuman review state
status: "success"Pending, approved, retry, or keep original
status: "error"Fix source, fix permissions, or remove from batch
status: "skipped"Confirm intentional skip or regenerate
convert.truncatedContinue the batch before claiming completion

This separation prevents a common quality problem: treating "converted successfully" as "safe to publish."

Keep Logs With the Build Record#

For CI and release workflows, store conversion reports with build artifacts or release notes. You do not need to keep every local development log forever, but release image jobs should be traceable.

The GetWebP CI integration guide covers pipeline setup, secret handling, structured output, and error handling. GitHub's Actions documentation explains artifacts and workflow logs. Google's WebP documentation explains the format being generated.

For a release build, keep at least:

  • the command
  • the CLI version event
  • the NDJSON report
  • the exit code
  • the output artifact path
  • the visual-review summary
  • any rejected or retried files

Those items make the work auditable without forcing future developers to reconstruct the run from a long terminal transcript.

Set a Retention Rule#

Decide how long reports should live. A pull-request check may only need short-term retention. A release migration may need the report kept with the release record. The rule should match the risk of the images and the chance of needing rollback evidence.

Use different retention for different work:

WorkflowSuggested retention logic
Local experimentKeep only until the branch decision is made
Pull requestKeep with CI artifacts long enough for review and merge
Release migrationKeep with release notes or deployment artifacts
Client handoffKeep with the delivery package and visual approval record
Incident rollbackKeep until the rollback and follow-up fix are closed

Make Logs Readable for Humans#

Even when structured output exists, provide a short human summary:

Command: npx -y getwebp ./public/images -o ./dist/images --recursive --quality 82 --format webp --json
Images scanned: 184
Converted: 176
Skipped: 6
Failed: 2
Exit code: 3
Report: conversion.ndjson
Decision: release blocked until failed files are triaged

This lets reviewers understand the run without opening the raw report first.

Good WebP conversion logs help developers make decisions. They show whether the command ran, whether the output set is complete, what failed, and where human review should focus next.

Jack avatar

Jack

GetWebP Editor

Jack writes GetWebP guides about local-first image conversion, WebP workflows, browser compatibility, and practical performance checks for teams that publish images on the web.