{"record":{"id":"35847651bb6951d4","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"tag-path-fetch-failed-err-as-error-mess","errorCode":null,"errorMessage":"${TAG} ${path} fetch failed: ${(err as Error).message}","messagePattern":"(.+?) (.+?) fetch failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"MemoryProxy/src/meta/client.ts","lineNumber":542,"sourceCode":"    const headers: Record<string, string> = {\n      \"Authorization\": `Bearer ${this.serviceToken}`,\n      \"x-tdai-service-id\": this.serviceId,\n      \"Content-Type\": \"application/json\",\n    };\n    if (this.userKey) {\n      headers[\"x-tdai-user-key\"] = this.userKey;\n    }\n\n    let resp: Response;\n    try {\n      resp = await this.fetcher(url, {\n        method: \"POST\",\n        headers,\n        body: JSON.stringify(body),\n        signal: AbortSignal.timeout(this.defaultTimeoutMs),\n      });\n    } catch (err) {\n      throw new Error(`${TAG} ${path} fetch failed: ${(err as Error).message}`);\n    }\n\n    if (!resp.ok) {\n      let detail = \"\";\n      try {\n        detail = await resp.text();\n      } catch { /* ignore */ }\n      console.log(\n        `[wb-debug] metadata-client req path=${path} status=${resp.status} url=${url} serviceId=${this.serviceId} userKey.len=${this.userKey?.length ?? 0} userKey.prefix=${(this.userKey ?? \"\").slice(0, 20)} serviceToken.len=${this.serviceToken?.length ?? 0} body.len=${detail.length} body.head=${detail.slice(0, 300)}`,\n      );\n      throw new Error(`${TAG} ${path} HTTP ${resp.status}${detail ? `: ${detail.slice(0, 200)}` : \"\"}`);\n    }\n\n    const env = (await resp.json()) as CoreEnvelope<T>;\n\n    if (env.code !== 0) {\n      throw new Error(`${TAG} ${path} envelope error ${env.code}: ${env.message ?? \"\"}`);\n    }","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryProxy/src/meta/client.ts#L524-L560","documentation":"MetaClient.fetch wraps the metadata-service HTTP POST; any exception thrown by fetch() itself (network error, DNS failure, timeout via AbortSignal.timeout) is rethrown with a prefixed message naming the path and underlying cause. This distinguishes transport-level failures from HTTP status and envelope errors, which have their own messages.","triggerScenarios":"createTask/updateTask/appendParticipationLog calls fetch and the request rejects before a response is returned: connection refused/reset, DNS resolution failure, TLS error, or defaultTimeoutMs elapsing (AbortError/TimeoutError).","commonSituations":"Metadata service down or wrong URL configured; corporate proxy/firewall blocking egress; timeout too low for slow networks; service DNS not resolvable inside the deployment environment.","solutions":["Confirm the metadata service URL is correct and reachable from the runtime (curl the endpoint)","Increase defaultTimeoutMs if timeouts are the cause (AbortError in message)","Check network egress/proxy/firewall rules for the deployment environment","Retry with backoff for transient network errors; inspect the inner error message after 'fetch failed:' for the root cause"],"exampleFix":"// before\nnew MetaClient({ ..., defaultTimeoutMs: 3000 });\n// after\nnew MetaClient({ ..., defaultTimeoutMs: 15000 }); // tolerate slow metadata service","handlingStrategy":"retry","validationCode":"// precheck connectivity\nconst reachable = await fetch(serviceUrl, { method: \"HEAD\", signal: AbortSignal.timeout(3000) }).then(() => true).catch(() => false);\nif (!reachable) throw new Error(\"metadata service unreachable before request\");","typeGuard":null,"tryCatchPattern":"try {\n  await client.createTask(body);\n} catch (e) {\n  if (/fetch failed:.*(TimeoutError|AbortError|ECONNRESET|ENOTFOUND)/i.test(e.message)) {\n    await backoffRetry(() => client.createTask(body), 3);\n    return;\n  }\n  throw e;\n}","preventionTips":["Set defaultTimeoutMs generously for production networks","Monitor metadata-service health and alert on DNS/egress failures","Retry only transport-level failures (this error), not HTTP/envelope errors","Inspect the inner message after 'fetch failed:' to classify the root cause"],"tags":["network","timeout","fetch","metadata"],"backgroundTag":"fetch-failed","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}