{"record":{"id":"6c73610a2d7f7e9d","repo":"Crosstalk-Solutions/project-nomad","slug":"res-message","errorCode":null,"errorMessage":"res.message","messagePattern":"res\\.message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"admin/inertia/components/DownloadURLModal.tsx","lineNumber":33,"sourceCode":"  suggestedURL,\n  onPreflightSuccess,\n  ...modalProps\n}) => {\n  const [url, setUrl] = useState<string>('')\n  const [messages, setMessages] = useState<string[]>([])\n  const [loading, setLoading] = useState<boolean>(false)\n\n  async function runPreflightCheck(downloadUrl: string) {\n    try {\n      setLoading(true)\n      setMessages([`Running preflight check for URL: ${downloadUrl}`])\n      const res = await api.downloadRemoteMapRegionPreflight(downloadUrl)\n      if (!res) {\n        throw new Error('An unknown error occurred during the preflight check.')\n      }\n\n      if ('message' in res) {\n        throw new Error(res.message)\n      }\n\n      setMessages((prev) => [\n        ...prev,\n        `Preflight check passed. Filename: ${res.filename}, Size: ${(res.size / (1024 * 1024)).toFixed(2)} MB`,\n      ])\n\n      if (onPreflightSuccess) {\n        onPreflightSuccess(downloadUrl)\n      }\n    } catch (error) {\n      console.error('Preflight check failed:', error)\n      setMessages((prev) => [...prev, `Preflight check failed: ${error.message}`])\n    } finally {\n      setLoading(false)\n    }\n  }\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Crosstalk-Solutions/project-nomad/blob/0bd1c6f4f9888d577fe232de06ac144bb8337131/admin/inertia/components/DownloadURLModal.tsx#L15-L51","documentation":"runPreflightCheck throws new Error(res.message) when the preflight response object contains a 'message' property. In this backend's convention, a message field on a preflight response signals a refusal or failure explanation (e.g. URL rejected, unreachable host), so the client rethrows it as the user-facing error text. The literal 'res.message' seen in error reports is just interpolation of that backend string.","triggerScenarios":"The downloadRemoteMapRegionPreflight endpoint returns 200 with { message: '...' } — e.g. the URL points to a disallowed host, the file exceeds size limits, the host is unreachable, or the URL is not a direct map-region archive link.","commonSituations":"User pastes a URL the backend's allowlist rejects, a link to an HTML page rather than the archive, a host that times out during HEAD probing, or an expired/signed URL whose probe returns an error page.","solutions":["Read the actual res.message content — it is the backend's specific reason and the primary diagnostic.","Verify the URL points directly to a downloadable map region archive on an allowed host.","If the message is unexpected, reproduce the backend's HEAD/GET probe against the URL with curl to see what the host returns.","Improve the backend to use a structured { success, error } shape instead of an ambiguous 'message' key so success payloads can't collide."],"exampleFix":"// before\nif ('message' in res) {\n  throw new Error(res.message)\n}\n// after (keep backend text but tag its origin)\nif ('message' in res) {\n  throw new Error(`Preflight refused: ${res.message}`)\n}","handlingStrategy":"type-guard","validationCode":"// nothing to run before the call; the guard is on the response\n// (validate the URL host against the backend allowlist client-side if known)","typeGuard":"type PreflightOk = { filename: string; size: number }\ntype PreflightRefused = { message: string }\nfunction isRefused(v: unknown): v is PreflightRefused {\n  return typeof v === 'object' && v !== null && typeof (v as any).message === 'string' && !('filename' in v)\n}","tryCatchPattern":"if (isRefused(res)) { setMessages((p) => [...p, res.message]); return } // don't throw for expected refusals","preventionTips":["Prefer structured { success, error } envelopes over a bare 'message' key","Show res.message verbatim — it is the backend's reason","Probe risky URLs manually before bulk operations"],"tags":["react","inertia","preflight","maps","error-message"],"backgroundTag":"api-error-message-response","analyzedSha":"0bd1c6f4f9888d577fe232de06ac144bb8337131","analyzedAt":"2026-08-27T05:34:15.424Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}