{"record":{"id":"0ffb3a336aeaac24","repo":"unclecode/crawl4ai","slug":"invalid-config","errorCode":null,"errorMessage":"Invalid config","messagePattern":"Invalid config","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"deploy/docker/static/playground/index.html","lineNumber":580,"sourceCode":"        async function pyConfigToJson() {\n            const code = cm.getValue().trim();\n            if (!code) return {};\n\n            // Server requires `type` alongside `code` (CrawlerRunConfig | BrowserConfig).\n            // The UI already tracks this in #cfg-type; omitting it always 400s Advanced Config.\n            const cfgType = document.getElementById('cfg-type').value;\n            const res = await authFetch('/config/dump', {\n                method: 'POST',\n                headers: { 'Content-Type': 'application/json' },\n                body: JSON.stringify({ type: cfgType, code }),\n            });\n\n            const statusEl = document.getElementById('cfg-status');\n            if (!res.ok) {\n                const msg = await res.text();\n                statusEl.textContent = '✖ config error';\n                statusEl.className = 'text-xs text-red-400';\n                throw new Error(msg || 'Invalid config');\n            }\n\n            statusEl.textContent = '✓ parsed';\n            statusEl.className = 'text-xs text-green-400';\n\n            return await res.json();\n        }\n\n        // ================ SERVER COMMUNICATION ================\n\n        // Update status UI\n        function updateStatus(status, time, memory, peakMemory) {\n            const statusEl = document.getElementById('execution-status');\n            const badgeEl = document.querySelector('#status-badge span:first-child');\n            const textEl = document.querySelector('#status-badge span:last-child');\n\n            statusEl.classList.remove('hidden');\n            badgeEl.className = 'w-3 h-3 rounded-full mr-2';","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/static/playground/index.html#L562-L598","documentation":"ArtifactNotFound raised when the artifact file exists and is regular but its mtime is older than ARTIFACT_TTL_SECONDS (default 3600 s). The file is unlinked (best-effort) and the lookup fails — artifacts are short-lived by design, and expiry is hidden behind the same not-found error.","triggerScenarios":"Fetching /artifact/{id} more than an hour (or configured TTL) after it was written; a pause between crawl and retrieval longer than the TTL; low TTL deployments.","commonSituations":"Retrying a downstream pipeline hours later; queuing artifact downloads behind slow workers; crawls run at night with retrieval the next morning.","solutions":["Retrieve artifacts promptly — within CRAWL4AI_ARTIFACT_TTL_SECONDS of creation","Persist important artifacts to your own storage immediately after the crawl response arrives","Raise CRAWL4AI_ARTIFACT_TTL_SECONDS on the server if longer retrieval windows are required"],"exampleFix":"# after crawl, download the artifact immediately instead of caching the id\nmeta = write_artifact(\"screenshot\", data)\n# fetch /artifact/{meta['artifact_id']} now, or store `data` yourself","handlingStrategy":"retry","validationCode":"import time\nTTL = int(os.environ.get(\"CRAWL4AI_ARTIFACT_TTL_SECONDS\", 3600))\ndef artifact_likely_alive(meta, now=None) -> bool:\n    return (now or time.time()) - meta[\"created_at\"] < TTL - 60  # 1 min slack","typeGuard":null,"tryCatchPattern":"try:\n    path, mime = resolve_artifact(meta[\"artifact_id\"])\nexcept ArtifactNotFound:\n    meta = await regenerate_artifact(...)  # expired -> re-crawl and re-store\n    path, mime = resolve_artifact(meta[\"artifact_id\"])","preventionTips":["Download artifacts immediately after the crawl response","Copy important artifacts to your own durable storage","Size your retrieval pipeline latency against CRAWL4AI_ARTIFACT_TTL_SECONDS"],"tags":["artifacts","not-found","ttl","expiry"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}