gildas-lormeau/SingleFile · error · Error

responseData.message

Error message

responseData.message

What it means

createContent throws an Error whose message is the GitHub API's `message` field from the JSON response body when the HTTP status is >= 400. This surfaces GitHub's own error text (e.g. "Bad credentials", "Not Found", "name already exists on the same branch", "API rate limit exceeded") directly to the caller.

Source

Thrown at src/lib/github/github.js:134

					return responseData;
				} else if (filenameConflictAction == CONFLICT_ACTION_PROMPT) {
					if (prompt) {
						path = await prompt(path);
						if (path) {
							return await createContent({ path, content, message });
						} else {
							return responseData;
						}
					} else {
						options.filenameConflictAction = CONFLICT_ACTION_UNIQUIFY;
						return await createContent({ path, content, message });
					}
				}
			}
			if (response.status < 400) {
				return responseData;
			} else {
				throw new Error(responseData.message);
			}
		} catch (error) {
			if (error.name != ABORT_ERROR_NAME) {
				throw error;
			}
		}

		function fetchContentData(method, body) {
			return fetch(`${GITHUB_API_URL}/${REPOS_PATH}/${userName}/${repositoryName}/${CONTENTS_PATH}/${path}`, {
				method,
				headers,
				body,
				signal
			});
		}
	}

	function splitFilename(filename) {

View on GitHub (pinned to 517fb7c5cf)

Solutions

  1. Log the error message to see GitHub's exact reason; branch on it (credentials vs not-found vs conflict vs rate limit).
  2. For "already exists" conflicts, fetch the current file's SHA and pass it to update the content instead of creating.
  3. For 401, regenerate the PAT/refresh the token and ensure required scopes (repo / Contents: write for fine-grained tokens).
  4. For 403 rate limit, add backoff and reduce request volume; check X-RateLimit-Remaining headers.
  5. Verify repo name, branch, and path spelling and that the branch exists.

Example fix

// before
await github.createContent({...}); // Error: sha wasn't supplied
// after
try {
  await github.createContent({..., content, message});
} catch (e) {
  if (/already exists|sha wasn't supplied/i.test(e.message)) {
    const existing = await github.getFileSha(path);
    await github.createContent({..., sha: existing.sha});
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight checks before createContent
if (!token || token.length < 20) throw new Error("GitHub token missing/short");
if (!/^[\w.-]+\/[\w.-]+$/.test(repo)) throw new Error("repo must be owner/name");
// check whether the file already exists to fetch its SHA for updates

Try / catch

try { await github.createContent(params); }
catch (e) {
  const msg = String(e.message);
  if (/Bad credentials/i.test(msg)) return reauthGitHub();
  if (/Not Found/i.test(msg)) return verifyRepoAndBranch();
  if (/already exists|sha/i.test(msg)) return updateWithSha(params);
  if (/rate limit/i.test(msg)) return retryWithBackoff();
  throw e;
}

Prevention

When it happens

Trigger: Uploading/creating a file where status >= 400: 401 bad or expired personal access token; 404 repo or branch/path does not exist; 422 commit conflict because the file changed and no SHA was supplied for update; 403 rate limit or resource not accessible.

Common situations: Token expired or rotated causing "Bad credentials"; writing to a repo path where the file already exists without passing its blob SHA (must use update); private repo with a fine-grained token lacking Contents write permission; hitting the 5000 req/hr REST limit in CI loops.

Related errors


AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01). Data as JSON: /api/errors/8d0c1b812ead9c2d. Report an issue: GitHub.