{"record":{"id":"ef3298867b865146","repo":"windmill-labs/windmill","slug":"invalid-pdf-source-object-typeof-source","errorCode":null,"errorMessage":"Invalid PDF source object${typeof source}","messagePattern":"Invalid PDF source object(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/apps/components/display/AppPdf.svelte","lineNumber":50,"sourceCode":"\tlet pdfSource: string | ArrayBuffer | undefined = $state(undefined)\n\n\tlet token = getContext<{ token?: string }>('AuthToken')\n\n\tasync function loadSource() {\n\t\tif (isPartialS3Object(source)) {\n\t\t\tpdfSource = await getS3File({\n\t\t\t\tsource: source.s3,\n\t\t\t\tstorage: source.storage,\n\t\t\t\tpresigned: source.presigned,\n\t\t\t\tappPath: $appPath,\n\t\t\t\tusername: $userStore?.username,\n\t\t\t\tworkspace,\n\t\t\t\ttoken: token?.token,\n\t\t\t\tisEditor,\n\t\t\t\tconfiguration\n\t\t\t})\n\t\t} else if (source && typeof source !== 'string' && !(source instanceof ArrayBuffer)) {\n\t\t\tthrow new Error('Invalid PDF source object' + typeof source)\n\t\t} else if (typeof source === 'string' && source?.startsWith('s3://')) {\n\t\t\tpdfSource = await getS3File({\n\t\t\t\tsource: source?.replace('s3://', ''),\n\t\t\t\tappPath: $appPath,\n\t\t\t\tusername: $userStore?.username,\n\t\t\t\tworkspace,\n\t\t\t\ttoken: token?.token,\n\t\t\t\tisEditor,\n\t\t\t\tconfiguration\n\t\t\t})\n\t\t} else {\n\t\t\tpdfSource = source\n\t\t}\n\t}\n\n\t$effect(() => {\n\t\tsource && loadSource()\n\t})","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/apps/components/display/AppPdf.svelte#L32-L68","documentation":"AppPdf.svelte's loadSource() validates the PDF display component's source: it must be a string URL or an ArrayBuffer. Anything else truthy (object, array, blob-like) throws 'Invalid PDF source object<type>'.","triggerScenarios":"A PDF viewer component whose source config resolves to a non-string, non-ArrayBuffer value, e.g. a step output object holding the PDF instead of its URL.","commonSituations":"Passing a fetch() Response or {data: ...} object directly; forgetting to await/download the PDF bytes into an ArrayBuffer; template interpolation returning a JSON object.","solutions":["Make the source resolve to a string URL (e.g. result.url) or convert the payload to an ArrayBuffer before assigning it","If the step returns binary, fetch the URL and pass response.arrayBuffer()","Check that the s3:// string form is used for workspace-stored PDFs"],"exampleFix":"// before\nsource: `${inputs1.result}` // object\n// after\nsource: await inputs1.result.arrayBuffer()","handlingStrategy":"validation","validationCode":"if (source && typeof source !== 'string' && !(source instanceof ArrayBuffer)) {\n  throw new TypeError(`PDF source must be string or ArrayBuffer, got ${typeof source}`)\n}","typeGuard":"function isValidPdfSource(s: unknown): s is string | ArrayBuffer {\n  return typeof s === 'string' || s instanceof ArrayBuffer\n}","tryCatchPattern":"try {\n  await loadSource()\n} catch (e) {\n  if (e.message.startsWith('Invalid PDF source object')) {\n    console.error('PDF source must be a URL string or ArrayBuffer', e)\n  } else throw e\n}","preventionTips":["Convert binary step outputs with response.arrayBuffer() before assigning to the PDF source","Use result.url rather than the whole result object","Test with the s3:// string form for workspace files"],"tags":["windmill-apps","configuration","type-mismatch"],"backgroundTag":"invalid-component-config-type","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}