{"record":{"id":"4caa7d2774b0d631","repo":"JuliusBrussee/caveman","slug":"cave-artifact-response-missing-artifact-id-4caa7d","errorCode":null,"errorMessage":"cave artifact response missing artifact_id","messagePattern":"cave artifact response missing artifact_id","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"packages/sdk/python/caveman_cloud/core.py","lineNumber":1183,"sourceCode":"        ``workflow``, and same stub format). :attr:`artifacts` exposes ``page``\n        as the mirror-named entry point; ``page_artifact`` stays as a\n        backwards-compatible alias.\n        \"\"\"\n        if options.get(\"strategy\") == \"verbatim\":\n            return value\n        # `workflow` mirrors the TS SDK body so both SDKs send the identical wire.\n        response = self._request(\n            \"/sdk/v1/artifacts\",\n            {\"value\": value, \"options\": options, \"workflow\": self.workflow},\n            extra_headers={\n                \"x-cave-artifact-envelope\": \"value-v1\",\n                \"x-cave-artifact-source\": str(options[\"source\"]),\n            },\n        )\n        if response.get(\"stored\") is False:\n            return value\n        if response.get(\"stored\") is not True or not isinstance(response.get(\"artifact_id\"), str) or not response[\"artifact_id\"].strip():\n            raise RuntimeError(\"cave artifact response missing artifact_id\")\n        content_type = options.get(\"content_type\") or \"application/json\"\n        return (\n            f\"[cave-artifact id={response['artifact_id']} source={options['source']} type={content_type}]\\n\"\n            f\"summary: artifact stored.\\n\"\n            f\"retrieve: authenticated GET /sdk/v1/artifacts/{response['artifact_id']} or trace.artifacts.get(\\\"{response['artifact_id']}\\\").\\n\"\n            f\"[/cave-artifact]\"\n        )\n\n    def get_artifact(self, artifact_id: str) -> Any:\n        \"\"\"Retrieve and JSON-decode one artifact produced by :meth:`page_artifact`.\"\"\"\n        if not isinstance(artifact_id, str) or not artifact_id.strip():\n            raise ValueError(\"artifact_id is required\")\n        return self._get(f\"/sdk/v1/artifacts/{quote(artifact_id, safe='')}\")\n\n    @property\n    def artifacts(self) -> \"_Artifacts\":\n        \"\"\"Artifact handle mirroring the TS ``trace.artifacts`` namespace.\n","sourceCodeStart":1165,"sourceCodeEnd":1201,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/sdk/python/caveman_cloud/core.py#L1165-L1201","documentation":"Error \"cave artifact response missing artifact_id\" thrown in JuliusBrussee/caveman.","triggerScenarios":"Thrown at packages/sdk/python/caveman_cloud/core.py:1183 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The cave artifact response lacked artifact_id; verify the server version and retry."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}