{"record":{"id":"6c9d527507d6f62b","repo":"iflytek/astron-agent","slug":"docker-compose-config-did-not-return-valid-json","errorCode":null,"errorMessage":"Docker Compose config did not return valid JSON","messagePattern":"Docker Compose config did not return valid JSON","errorType":"console","errorClass":"GateError","httpStatus":null,"severity":"error","filePath":"docker/astronAgent/scripts/verify_security_contract.py","lineNumber":184,"sourceCode":"        \"'config --format json' is required\"\n    )\n\n\ndef _render_compose(compose_file: Path) -> Mapping[str, Any]:\n    base_command = _select_compose_command(compose_file)\n    completed = subprocess.run(\n        list(base_command) + [\"-f\", compose_file.name, \"config\", \"--format\", \"json\"],\n        cwd=str(compose_file.parent),\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n        universal_newlines=True,\n        check=False,\n    )\n\n    try:\n        rendered = json.loads(completed.stdout)\n    except (json.JSONDecodeError, TypeError) as exc:\n        raise GateError(\"Docker Compose config did not return valid JSON\") from exc\n    if not isinstance(rendered, dict):\n        raise GateError(\"Docker Compose config returned an unexpected JSON root\")\n    return rendered\n\n\ndef _mapping(value: Any) -> Mapping[str, Any]:\n    return value if isinstance(value, dict) else {}\n\n\ndef _mounts(service: Mapping[str, Any], target: str) -> List[Mapping[str, Any]]:\n    volumes = service.get(\"volumes\", [])\n    if not isinstance(volumes, list):\n        return []\n    return [\n        volume\n        for volume in volumes\n        if isinstance(volume, dict) and volume.get(\"target\") == target\n    ]","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/docker/astronAgent/scripts/verify_security_contract.py#L166-L202","documentation":"_render_compose runs the selected Compose command with 'config --format json' and parses stdout with json.loads. If the output is not valid JSON (JSONDecodeError or TypeError, e.g. non-string stdout), it wraps the failure in GateError('Docker Compose config did not return valid JSON'). This guards against Compose implementations that ignore the --format json flag and emit YAML or human-readable text.","triggerScenarios":"The chosen compose implementation exits 0 but prints YAML/human text instead of JSON for 'config --format json' (older/v1 or aliased implementations); stdout polluted by warnings/pre-banner text; or the command output is None.","commonSituations":"Shell alias or wrapper intercepting docker-compose; compose v1 accepting --format but rendering text; plugin printing deprecation warnings on stdout; CI shim that logs before the command output.","solutions":["Upgrade to Docker Compose v2 so 'config --format json' emits pure JSON on stdout.","Run the command manually and inspect stdout for non-JSON prefixes (warnings, banners) and remove their source.","Check for shell aliases/wrappers around docker compose in the execution environment (unalias, use absolute path).","Capture stdout separately from stderr (2>/dev/null) when testing to confirm which stream carries the noise."],"exampleFix":"// diagnostic before fix\ndocker compose config --format json | head -c 200   # shows YAML or warning text\n// after upgrade\ndocker compose version  # v2.x\ndocker compose config --format json | python -m json.tool > /dev/null  # ok","handlingStrategy":"validation","validationCode":"import json, subprocess\nout = subprocess.run([\"docker\",\"compose\",\"-f\",f,\"config\",\"--format\",\"json\"], capture_output=True, text=True).stdout\njson.loads(out)  # raises early if not JSON","typeGuard":"def is_json_object(s: str) -> bool:\n    import json\n    try:\n        return isinstance(json.loads(s), dict)\n    except (json.JSONDecodeError, TypeError):\n        return False","tryCatchPattern":"try:\n    cfg = render_compose(f)\nexcept GateError as e:\n    if \"valid JSON\" in str(e):\n        log(compose_raw_stdout)  # inspect non-JSON noise\n    raise","preventionTips":["Avoid wrappers/aliases that prepend text to compose output.","Upgrade to Compose v2.","Test 'config --format json' output purity in CI."],"tags":["docker-compose","json","parse-error"],"backgroundTag":"invalid-json-response","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}