zylon-ai/private-gpt · error · Error

Generator did not return valid JSON.

Error message

Generator did not return valid JSON.

What it means

This RuntimeError is raised by update_anthropic_version in scripts/update_claude_specs.py (line 71). It reads pyproject.toml, applies re.subn with the exact pattern "anthropic>=[\d.]+" (a double-quoted dependency string whose version is only digits and dots), and aborts when nothing matched. It means the anthropic floor-version dependency the script is designed to bump no longer appears in pyproject.toml in that exact literal form (today it is 'anthropic>=0.120.2' on line 54 under the llm-anthropic extra).

Source

Thrown at ui/index.html:4812

      ].join("\n");
    }

    function extractJsonObject(text) {
      const trimmed = String(text || "").trim();
      if (!trimmed) throw new Error("Empty response from generator.");
      try {
        return JSON.parse(trimmed);
      } catch {}
      const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
      if (fenced) {
        try { return JSON.parse(fenced[1].trim()); } catch {}
      }
      const start = trimmed.indexOf("{");
      const end = trimmed.lastIndexOf("}");
      if (start >= 0 && end > start) {
        return JSON.parse(trimmed.slice(start, end + 1));
      }
      throw new Error("Generator did not return valid JSON.");
    }

    function normalizeAppearanceSuggestion(candidate, fallbackBrief = "") {
      const appearance = {
        ...DEFAULT_APPEARANCE,
        ...candidate,
        brief: typeof candidate?.brief === "string" && candidate.brief.trim() ? candidate.brief.trim() : fallbackBrief,
        themeMode: ["light", "dark", "auto"].includes(candidate?.themeMode) ? candidate.themeMode : DEFAULT_APPEARANCE.themeMode,
        palette: {
          ...DEFAULT_APPEARANCE.palette,
          ...(candidate?.palette || {})
        },
        features: {
          ...DEFAULT_APPEARANCE.features,
          ...(candidate?.features || {})
        }
      };
      ["accent", "secondary", "surface", "background"].forEach(key => {

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Check pyproject.toml line 54 and restore the exact shape "anthropic>=X.Y.Z" (double quotes, no spaces, digits-and-dots-only version) inside the llm-anthropic extra.
  2. If an upper bound is intentionally kept (e.g. "anthropic>=0.120.2,<1"), broaden the regex in scripts/update_claude_specs.py line 66 to r'"anthropic>=[\d.]+[^"]*"' and update the reader regex at line 44 to r'"anthropic>=([\d.]+)' so both sides handle the suffix.
  3. If the operator or quote style changed project-wide, align both patterns (lines 44 and 66) with the new convention — reader and writer must stay in sync or the script will report '<not found>' and then raise.
  4. Re-run python scripts/update_claude_specs.py and verify it bumps the floor and runs 'uv lock' successfully.

Example fix

# pyproject.toml [project.optional-dependencies] llm-anthropic — before (upper bound breaks [\d.]+ then '"')
llm-anthropic = [
    "langchain-anthropic>=1.4.3",
    "anthropic>=0.120.2,<1",
]

# after (plain floor the script understands)
llm-anthropic = [
    "langchain-anthropic>=1.4.3",
    "anthropic>=0.120.2",
]

# or, to keep the upper bound, change scripts/update_claude_specs.py:66 to:
#     r'"anthropic>=[\d.]+[^"]*"'
Defensive patterns

Strategy: validation

Validate before calling

# Pre-flight check mirroring the reader (line 44) and writer (line 66) regexes
import re
from pathlib import Path

PYPROJECT_FILE = Path("pyproject.toml")
READ_RE = re.compile(r'"anthropic>=([\d.]+)')
WRITE_RE = re.compile(r'"anthropic>=[\d.]+"')

def anthropic_pin_is_rewriteable() -> bool:
    source = PYPROJECT_FILE.read_text(encoding="utf-8")
    return bool(READ_RE.search(source)) and bool(WRITE_RE.search(source))

# call before running scripts/update_claude_specs.py
if not anthropic_pin_is_rewriteable():
    raise SystemExit("pyproject.toml: anthropic floor-version pin missing or not rewriteable — fix before sync")

Try / catch

import subprocess, sys

try:
    subprocess.run([sys.executable, "scripts/update_claude_specs.py"], check=True)
except subprocess.CalledProcessError:
    # Deterministic failure — inspect the anthropic entry in [project.optional-dependencies].
    # Do not retry; fix the dependency string or the regexes at lines 44/66 first.
    sys.exit("update_claude_specs failed: check the anthropic>= pin in pyproject.toml (llm-anthropic extra)")

Prevention

When it happens

Trigger: Shapes of pyproject.toml that yield count == 0: (1) the specifier operator changed, e.g. 'anthropic~=0.120.2' or 'anthropic==0.120.2'; (2) an upper bound or marker was added so characters other than [\d.] precede the closing quote, e.g. "anthropic>=0.120.2,<1" — the class [\d.] stops at the comma and the required '"' never follows; (3) whitespace inside the string like "anthropic >= 0.120.2"; (4) single-quoted (literal) TOML strings; (5) the dependency was dropped from the llm-anthropic extra or moved/renamed. Like error 440, it only fires when the PyPI latest version differs from current_anthropic_version()'s match, via main() at line 109.

Common situations: Hit in the scheduled update-claude-specs CI job after a maintainer tightens the dependency range (adds <1 upper bound — a common breaking-change policy), switches to PEP 440 compatible release ~=, or reformats pyproject.toml with a tool that normalizes quotes/spacing. Silent until Anthropic publishes a new version, at which point the automation fails instead of opening its PR.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/fc1a556751593630. Report an issue: GitHub.