{"record":{"id":"64f43cb107210a1b","repo":"koala73/worldmonitor","slug":"webhook-url-dns-resolution-failed-message","errorCode":null,"errorMessage":"Webhook URL DNS resolution failed: ${message}","messagePattern":"Webhook URL DNS resolution failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"warning","filePath":"api/_notification-webhook-ssrf.ts","lineNumber":248,"sourceCode":" * Fail fast at registration when the webhook hostname currently resolves to a\n * private or reserved address. Delivery repeats this check (and pins its\n * connection) because DNS can change after registration.\n */\nexport async function assertNotificationWebhookRegistrationUrlSafe(\n  rawUrl: string,\n  resolveHostname: ResolveHostname = defaultResolveHostname,\n): Promise<void> {\n  const staticError = blockedNotificationWebhookUrlReason(rawUrl);\n  if (staticError) throw new Error(staticError);\n\n  const hostname = new URL(rawUrl).hostname.toLowerCase();\n  if (isIpLiteral(hostname)) return;\n  let resolvedAddresses: string[];\n  try {\n    resolvedAddresses = await resolveHostname(hostname);\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    throw new Error(`Webhook URL DNS resolution failed: ${message}`);\n  }\n  if (!resolvedAddresses.length) throw new Error('Webhook URL DNS resolution returned no addresses');\n  if (resolvedAddresses.some(isBlockedNotificationResolvedAddress)) {\n    throw new Error('Webhook URL must not point to a private/local address');\n  }\n}\n","sourceCodeStart":230,"sourceCodeEnd":255,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/api/_notification-webhook-ssrf.ts#L230-L255","documentation":"saveImportedFramework() rejects frameworks whose systemPromptAppend exceeds MAX_INSTRUCTIONS_LEN = 2000 characters. The check uses .length on the raw string, and the thrown message reports both the limit and the actual length so the offender can be trimmed precisely. It fires after the library-cap check but before the duplicate-name check.","triggerScenarios":"Importing or pasting an analysis framework with fw.systemPromptAppend.length greater than 2000, e.g., a prompt template copied from an LLM tool with no length limit.","commonSituations":"Large prompt templates authored elsewhere with different limits; instructions inflated by indentation/whitespace or invisible characters; iterating on a framework that grows over edits.","solutions":["Trim the instructions to 2000 characters or fewer; the error message states the exact overflow","Compress the wording or split the framework into two focused frameworks","Strip redundant whitespace/indentation before importing","Validate the length in the import UI before calling saveImportedFramework()"],"exampleFix":"// before\nsaveImportedFramework({ id, name, description, systemPromptAppend }); // throws at >2000 chars\n\n// after\nconst MAX = 2000;\nif (systemPromptAppend.length > MAX) {\n  showWarning(`Instructions are ${systemPromptAppend.length} chars; limit is ${MAX}.`);\n  return;\n}\nsaveImportedFramework({ id, name, description, systemPromptAppend });","handlingStrategy":"validation","validationCode":"const MAX = 2000;\nif (fw.systemPromptAppend.length > MAX) {\n  showWarning(`Instructions are ${fw.systemPromptAppend.length} chars; limit is ${MAX}.`);\n  return;\n}\nsaveImportedFramework(fw);","typeGuard":null,"tryCatchPattern":"try {\n  saveImportedFramework(fw);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Instructions exceed')) highlightInstructionsEditor();\n  else throw e;\n}","preventionTips":["Show a live character counter on the instructions editor capped at 2000","Trim pasted templates before import; whitespace often carries hundreds of chars","Validate on input, not on submit"],"tags":["validation","input-length","analysis-frameworks","local-storage"],"backgroundTag":"input-too-long","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}