{"record":{"id":"3ebe66d853c19893","repo":"can1357/oh-my-pi","slug":"destination-option-endpoint-must-use-http-or-https","errorCode":null,"errorMessage":"Destination option endpoint must use HTTP or HTTPS","messagePattern":"Destination option endpoint must use HTTP or HTTPS","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-image-hosts.ts","lineNumber":311,"sourceCode":"\t\t\t}\n\t\t\tconst sizesResponse = await fetchFor(config)(getSizesUrl, { method: \"GET\" });\n\t\t\tconst sizes = await jsonResponse(sizesResponse, \"flickr\");\n\t\t\treturn publication(\"flickr\", request, largestFlickrSource(sizes), { remoteId: photoId });\n\t\t},\n\t};\n}\n\nfunction requiredEndpoint(config: DestinationRuntimeConfig): string {\n\tconst endpoint = optionString(config, \"endpoint\");\n\tif (!endpoint) throw new Error(\"Missing required destination option: endpoint\");\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(endpoint);\n\t} catch {\n\t\tthrow new Error(\"Destination option endpoint must be an absolute URL\");\n\t}\n\tif (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n\t\tthrow new Error(\"Destination option endpoint must use HTTP or HTTPS\");\n\t}\n\treturn url.href;\n}\n\nfunction createCheveretoUploader(config: DestinationRuntimeConfig): BlobUploader {\n\tconst endpoint = requiredEndpoint(config);\n\tconst apiKey = requireCredential(config, \"apiKey\");\n\n\treturn {\n\t\tdestination: \"chevereto\",\n\t\tasync upload(request) {\n\t\t\tconst response = await fetchFor(config)(endpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: multipartFile(request, \"source\", { key: apiKey, format: \"json\" }),\n\t\t\t});\n\t\t\tconst payload = await jsonResponse(response, \"chevereto\");\n\t\t\tconst image = nestedRecord(payload, \"image\", \"chevereto\");\n\t\t\tconst url = directUrl(requiredString(image, \"url\", \"chevereto\"), \"chevereto\");","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-image-hosts.ts#L293-L329","documentation":"requiredEndpoint() throws this when the endpoint parses as an absolute URL but its protocol is neither https: nor http: (e.g. ftp:, file:, ws:). Only HTTP(S) endpoints are supported for image-host uploads.","triggerScenarios":"Endpoint values like 'ftp://host/upload', 'file:///path', or accidentally including a scheme such as 'javascript:' or a custom protocol in the destination config.","commonSituations":"Copy-pasting a URL from a non-HTTP tool, intentionally pointing at an internal FTP drop, or a typo like 'httpss://' being parsed as an unknown scheme.","solutions":["Change the endpoint scheme to https:// (preferred) or http:// for local testing","Remove any custom/non-HTTP protocol from the endpoint value","If you genuinely need a non-HTTP transfer, that destination type is unsupported — use an HTTP front-end"],"exampleFix":"// before\n\"endpoint\": \"ftp://chev.example.com/upload\"\n// after\n\"endpoint\": \"https://chev.example.com/upload\"","handlingStrategy":"validation","validationCode":"const u = new URL(config.options.endpoint);\nif (u.protocol !== \"https:\" && u.protocol !== \"http:\") throw new Error(`endpoint scheme '${u.protocol}' unsupported; use http(s)`);","typeGuard":"function isHttpUrl(value: unknown): value is string {\n\tif (typeof value !== \"string\") return false;\n\ttry { const u = new URL(value); return u.protocol === \"https:\" || u.protocol === \"http:\"; } catch { return false; }\n}","tryCatchPattern":"try {\n\tconst href = requiredEndpoint(config);\n} catch (err) {\n\tif (err instanceof Error && err.message.includes(\"HTTP or HTTPS\")) {\n\t\t// rewrite scheme to https and retry once\n\t}\n\tthrow err;\n}","preventionTips":["Use https:// endpoints exclusively in production","Never paste ftp://, file://, or custom-scheme URLs into endpoint fields","Normalize schemes at config ingest (e.g. ftp:// -> https://) or reject early","Add endpoint protocol checks to your config linter"],"tags":["configuration","url","validation"],"backgroundTag":"unsupported-protocol","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}