jlcodes99/cockpit-tools · error
PROVIDER_CREDENTIAL_INVALID
PROVIDER_CREDENTIAL_INVALID
Error message
PROVIDER_CREDENTIAL_INVALID
What it means
Thrown when upserting a provider from a credential pair and either the normalized base URL or the sanitized API key is empty/invalid. The service requires both a valid Codex-compatible base URL and a non-empty key before it will locate or create a provider. It fires before any store lookup, so nothing is persisted.
Source
Thrown at src/services/codexModelProviderService.ts:949
): Promise<CodexModelProvider> {
return updateCodexModelProvider(providerId, { integrationType });
}
export async function deleteCodexModelProvider(providerId: string): Promise<void> {
const providers = await ensureProvidersLoaded();
const next = providers.filter((item) => item.id !== providerId);
if (next.length === providers.length) return;
await writeProviders(next);
}
export async function upsertCodexModelProviderFromCredential(
input: UpsertFromCredentialInput,
): Promise<CodexModelProvider> {
const apiBaseUrl = normalizeBaseUrlForStore(input.apiBaseUrl);
const normalizedBaseUrl = normalizeCodexModelProviderBaseUrl(apiBaseUrl);
const apiKey = sanitizeApiKey(input.apiKey);
if (!normalizedBaseUrl || !apiKey) {
throw new Error('PROVIDER_CREDENTIAL_INVALID');
}
const providers = await ensureProvidersLoaded();
let provider = findCodexModelProviderById(providers, input.providerId);
if (!provider) {
provider = findCodexModelProviderByBaseUrl(providers, apiBaseUrl);
}
if (!provider) {
const now = Date.now();
const wireApi = normalizeWireApi(input.wireApi);
provider = {
id: createProviderId(),
name:
sanitizeName(input.providerName ?? '') ||
deriveProviderNameFromBaseUrl(apiBaseUrl),
baseUrl: apiBaseUrl,
sourceTag: sanitizeName(input.sourceTag ?? '') || undefined,
modelCatalog:View on GitHub (pinned to 1ed8b77992)
Solutions
- Ensure apiBaseUrl is a full, valid URL the Codex normalizer accepts (e.g. https://host).
- Ensure apiKey is a non-empty real secret with no surrounding whitespace or placeholder text.
- Log/check the values after sanitizeApiKey/normalizeCodexModelProviderBaseUrl to see which one is empty before calling the API.
Example fix
// before
await upsertProviderFromCredential({ apiBaseUrl: 'localhost:8080', apiKey: '' });
// after
const apiBaseUrl = 'https://localhost:8080';
const apiKey = process.env.MY_API_KEY?.trim();
if (!apiKey) throw new Error('set MY_API_KEY before syncing the provider');
await upsertProviderFromCredential({ apiBaseUrl, apiKey }); Defensive patterns
Strategy: validation
Validate before calling
function isCredentialValid(apiBaseUrl, apiKey) {
let url;
try { url = new URL(apiBaseUrl); } catch { return false; }
return (url.protocol === 'https:' || url.protocol === 'http:')
&& typeof apiKey === 'string' && apiKey.trim().length > 0;
} Try / catch
try {
await upsertProviderFromCredential(input);
} catch (e) {
if (e.message === 'PROVIDER_CREDENTIAL_INVALID') {
console.error('Check apiBaseUrl scheme/host and that apiKey is a non-empty trimmed secret.');
} else throw e;
} Prevention
- Validate the URL with new URL() and require http(s) before submitting.
- Never pass placeholder strings like 'YOUR_API_KEY'; check env vars resolved to non-empty values.
- Trim user input on both fields before calling the API.
When it happens
Trigger: Calling the credential upsert with input.apiBaseUrl that fails normalizeCodexModelProviderBaseUrl (missing scheme, unsupported host); input.apiKey empty or rejected by sanitizeApiKey (e.g. whitespace/placeholder); both fields blank in a form submit.
Common situations: User pasted a base URL without https://; trailing garbage or wrong host for a Codex endpoint; API key field left blank or containing 'YOUR_KEY' placeholder; env/config interpolation produced an empty string.
Related errors
- Codex Agent Identity credentials are incomplete
- invalidJsonMessage
- messages.noItems
- messages.providerMismatch
- invalid_bundle_root
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/6d08049c28d405e6.
Report an issue: GitHub.