{"record":{"id":"10c3c8b164dc582a","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"cos-generationlogretentiondays-must-be-a-non-negat","errorCode":null,"errorMessage":"cos.generationLogRetentionDays must be a non-negative integer","messagePattern":"cos\\.generationLogRetentionDays must be a non-negative integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"MemoryCore/src/gateway/config.ts","lineNumber":612,"sourceCode":"  };\n\n  // Worker config\n  const workerConfig = obj(fileConfig, \"worker\");\n  const worker: WorkerConfig = {\n    pollMs: envInt(\"WORKER_POLL_MS\") ?? num(workerConfig, \"pollMs\") ?? 200,\n    concurrency: envInt(\"WORKER_CONCURRENCY\") ?? num(workerConfig, \"concurrency\") ?? 60,\n  };\n\n  // COS extra config\n  const cosConfig = obj(fileConfig, \"cos\");\n  const cos: CosExtraConfig = {\n    domain: env(\"COS_DOMAIN\") ?? str(cosConfig, \"domain\"),\n    generationLogRetentionDays: envInt(\"COS_GENERATION_LOG_RETENTION_DAYS\")\n      ?? num(cosConfig, \"generationLogRetentionDays\")\n      ?? 30,\n  };\n  if (!Number.isInteger(cos.generationLogRetentionDays) || cos.generationLogRetentionDays < 0) {\n    throw new Error(\"cos.generationLogRetentionDays must be a non-negative integer\");\n  }\n\n  // Observability config (yaml: observability.{otel,clickhouse,kafka}, env 兜底)\n  const observabilityConfig = obj(fileConfig, \"observability\");\n\n  // OTel config\n  const otelConfig = obj(observabilityConfig, \"otel\");\n  const otel: OTelConfig = {\n    enabled: otelConfig.enabled !== undefined\n      ? Boolean(otelConfig.enabled)\n      : env(\"TDAI_OTEL_ENABLED\") === \"true\",\n    endpoint: str(otelConfig, \"endpoint\") ?? env(\"OTEL_EXPORTER_OTLP_ENDPOINT\") ?? \"http://localhost:4317\",\n    protocol: (str(otelConfig, \"protocol\") ?? env(\"OTEL_EXPORTER_OTLP_PROTOCOL\") ?? \"grpc\") as \"grpc\" | \"http/protobuf\",\n    serviceName: str(otelConfig, \"serviceName\") ?? env(\"OTEL_SERVICE_NAME\") ?? \"core\",\n    serviceVersion: str(otelConfig, \"serviceVersion\") ?? \"1.0.0\",\n    tenantId: str(otelConfig, \"tenantId\") ?? env(\"OTEL_TENANT_ID\") ?? \"\",\n    logExportInterval: num(otelConfig, \"logExportInterval\") ?? envInt(\"OTEL_LOG_EXPORT_INTERVAL\") ?? 5,\n  };","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/gateway/config.ts#L594-L630","documentation":"During loadGatewayConfig, the COS (object storage) section's generationLogRetentionDays is resolved from env COS_GENERATION_LOG_RETENTION_DAYS, yaml cos.generationLogRetentionDays, or defaults to 30. The gateway validates the final value must be an integer >= 0 and throws at startup otherwise. This is fail-fast config validation for generation-log retention.","triggerScenarios":"Setting COS_GENERATION_LOG_RETENTION_DAYS to a non-integer (e.g. \"7.5\", \"30d\", \"\") or a negative number; putting generationLogRetentionDays: -1 or a decimal/string in the cos: block of the gateway yaml.","commonSituations":"Typo or unit suffix in env value (\"30d\", \"3 weeks\"); operator intended \"disable retention\" by setting -1 (must use 0, which retains nothing/forever per semantics); YAML type coercion producing a float; stale env var from an old deployment overriding a fixed yaml value.","solutions":["Fix COS_GENERATION_LOG_RETENTION_DAYS to a non-negative integer string, e.g. 30, or unset it to fall back to yaml/default.","Fix cos.generationLogRetentionDays in the gateway yaml to an integer >= 0.","To disable retention clearing, set 0 (valid) rather than a negative number.","Check which layer wins (env beats yaml): echo \"$COS_GENERATION_LOG_RETENTION_DAYS\" and remove the stale override."],"exampleFix":"// before (env)\nCOS_GENERATION_LOG_RETENTION_DAYS=-1\n// after\nCOS_GENERATION_LOG_RETENTION_DAYS=30\n// or yaml: cos:\n//   generationLogRetentionDays: 30","handlingStrategy":"validation","validationCode":"const raw = process.env.COS_GENERATION_LOG_RETENTION_DAYS;\nif (raw !== undefined && (!Number.isInteger(Number(raw)) || Number(raw) < 0)) {\n  throw new Error(`COS_GENERATION_LOG_RETENTION_DAYS must be a non-negative integer, got: ${raw}`);\n}","typeGuard":"function isValidRetentionDays(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0;\n}","tryCatchPattern":"try {\n  const cfg = loadGatewayConfig();\n} catch (err) {\n  if (err.message.includes('generationLogRetentionDays')) {\n    console.error('Fix COS_GENERATION_LOG_RETENTION_DAYS or cos.generationLogRetentionDays in yaml: must be an integer >= 0');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Validate env/config values in CI with a config lint step before deploy","Never encode units (\"30d\") in numeric config fields","Use 0, not negative numbers, to express retention-disable semantics","Document precedence: env overrides yaml, so audit both layers"],"tags":["configuration","validation","startup"],"backgroundTag":"invalid-config-value","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}