gildas-lormeau/SingleFile · error · Error

error.message + " (GitHub)"

Error message

error.message + " (GitHub)"

What it means

saveToGitHub wraps any error thrown while uploading a captured page to a GitHub repository via the GitHub client (client.upload). It rethrows the underlying message with an " (GitHub)" suffix and keeps the original error as cause. The suffix tells the caller which save destination failed.

Source

Thrown at src/core/bg/downloads.js:482

		if (authInfo) {
			await config.setDropboxAuthInfo(authInfo);
		} else {
			await config.removeDropboxAuthInfo();
		}
	}
	return authInfo;
}

async function saveToGitHub(taskId, filename, content, githubToken, githubUser, githubRepository, githubBranch, { filenameConflictAction, prompt }) {
	try {
		const taskInfo = business.getTaskInfo(taskId);
		if (!taskInfo || !taskInfo.cancelled) {
			const client = new GitHub(githubToken, githubUser, githubRepository, githubBranch);
			business.setCancelCallback(taskId, () => client.abort());
			return await client.upload(filename, content, { filenameConflictAction, prompt });
		}
	} catch (error) {
		throw new Error(error.message + " (GitHub)", { cause: error });
	}
}

async function saveToS3(taskId, filename, blob, domain, region, bucket, accessKey, secretKey, { filenameConflictAction, prompt }) {
	try {
		const taskInfo = business.getTaskInfo(taskId);
		if (!taskInfo || !taskInfo.cancelled) {
			const client = new S3(region, bucket, accessKey, secretKey, domain);
			business.setCancelCallback(taskId, () => client.abort());
			return await client.upload(filename, blob, { filenameConflictAction, prompt });
		}
	} catch (error) {
		throw new Error(error.message + " (S3)", { cause: error });
	}
}

async function saveWithWebDAV(taskId, filename, content, url, username, password, { filenameConflictAction, prompt }) {
	try {

View on GitHub (pinned to 517fb7c5cf)

Solutions

  1. Inspect error.cause for the original message and verify the GitHub token is valid and has repo write scope
  2. Confirm githubUser, githubRepository and githubBranch exist and match exactly (case-sensitive)
  3. Check network connectivity and retry the save
  4. Set filenameConflictAction to 'overwrite' or 'uniquify' to avoid conflict-prompt failures

Example fix

// before
throw new Error('upload failed: 401 Bad credentials');
// after
// wrapper adds context; fix root cause by refreshing the token:
// const client = new GitHub(await getFreshToken(), user, repo, branch);
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling save
if (!githubToken || !githubUser || !githubRepository || !githubBranch) {
  throw new Error('Missing GitHub save configuration');
}

Type guard

function hasGithubConfig(o) {
  return typeof o.token === 'string' && o.token.length > 0 &&
    typeof o.user === 'string' && typeof o.repo === 'string' && typeof o.branch === 'string';
}

Try / catch

try {
  await saveToGitHub(taskId, filename, content, githubOpts);
} catch (error) {
  if (error.message.endsWith('(GitHub)')) {
    console.error('GitHub save failed:', error.cause);
  } else { throw error; }
}

Prevention

When it happens

Trigger: Any failure inside new GitHub(token, user, repo, branch).upload(filename, content, {filenameConflictAction, prompt}) invoked from downloadContent/downloadCompressedContent, including invalid token, bad repo/branch, network failure, or abort/cancel errors.

Common situations: Expired or revoked GitHub personal access token; repository or branch renamed/deleted; token lacking repo scope; filename conflicts requiring user prompt in a background context where prompting is unavailable; offline network.

Related errors


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