{"record":{"id":"68a6bfc86537fc06","repo":"langgenius/dify","slug":"unknown-68a6bf","errorCode":"Unknown","errorMessage":"--file ${parsed.varname}: upload of ${parsed.path} failed: ${(err as Error).message}","messagePattern":"--file (.+?): upload of (.+?) failed: (.+?)","errorType":"error_code","errorClass":"BaseError","httpStatus":null,"severity":"error","filePath":"cli/src/commands/run/app/file-flags.ts","lineNumber":102,"sourceCode":"  const result: Record<string, unknown> = {}\n\n  for (const raw of rawFlags) {\n    const parsed = parseFileFlag(raw)\n\n    if (parsed.kind === 'remote') {\n      const filename = new URL(parsed.url).pathname.split('/').pop() ?? ''\n      result[parsed.varname] = {\n        type: difyFileType(filename),\n        transfer_method: 'remote_url',\n        url: parsed.url,\n      }\n    } else {\n      const filename = basename(parsed.path)\n      let uploaded: { id: string }\n      try {\n        uploaded = await upload(appId, parsed.path)\n      } catch (err) {\n        throw new BaseError({\n          code: ErrorCode.Unknown,\n          message: `--file ${parsed.varname}: upload of ${parsed.path} failed: ${(err as Error).message}`,\n          cause: err,\n        })\n      }\n      result[parsed.varname] = {\n        type: difyFileType(filename),\n        transfer_method: 'local_file',\n        upload_file_id: uploaded.id,\n      }\n    }\n  }\n\n  return result\n}\n","sourceCodeStart":84,"sourceCodeEnd":118,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/cli/src/commands/run/app/file-flags.ts#L84-L118","documentation":"Thrown by `resolveFileInputs` (file-flags.ts:102) wrapping any failure from the `upload` callback (a `FileUploadClient.upload` call) in a `BaseError` with code `unknown` (exit 1). The original error is preserved via `cause`. The message echoes the varname, the local path, and the underlying error message — so the root cause (network, 4xx, file not found, size limit) appears inline.","triggerScenarios":"Local file (`key=@path`) upload to Dify's file-upload endpoint fails: file does not exist, is unreadable, exceeds the server size limit, the workspace/app rejects it (403/422), the token lacks upload scope, or the network drops mid-upload.","commonSituations":"Path typo / wrong cwd; file permissions; expired or unscoped API token; Dify server enforces a max upload size; transient network blip; the app was deleted between parse and upload.","solutions":["Inspect the embedded `(err as Error).message` — it carries the real HTTP status / fs error.","Verify the path is readable: `ls -l <path>` from the same cwd the CLI runs in.","Re-auth if the underlying error is 401/403: `difyctl auth login`.","Retry on transient network/5xx; shrink the file if the server reports a size limit."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { access } from 'node:fs/promises'\n// Pre-check readability before upload\nasync function ensureReadable(path: string): Promise<void> {\n  await access(path, fs.constants.R_OK)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await resolveFileInputs(appId, files, upload)\n} catch (err) {\n  if (err instanceof BaseError && err.code === ErrorCode.Unknown &&\n      /^--file .*: upload of .* failed:/.test(err.message)) {\n    // inspect err.cause for the real HTTP/fs error and branch on it\n  }\n  throw err\n}","preventionTips":["Verify the file path is readable from the CLI's cwd before running.","Keep API tokens scoped and fresh to avoid 401/403 on upload.","Retry transient network/5xx; shrink files that breach server limits.","Inspect the embedded `(err).message` and `err.cause` for the true root cause."],"tags":["cli","file-upload","network","error-wrapping","difyctl","typescript"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}