BigPizzaV3/CodexPlusPlus · error · Error
请在设置中填写有效 API Key
Error message
请在设置中填写有效 API Key
What it means
For the external API channel, apiConfig() requires a non-empty API key containing no CR/LF characters. A missing or newline-contaminated key would break the Authorization header and leak across lines, so it throws immediately.
Solutions
- Enter a valid API key in the settings panel
- Re-copy the key making sure there are no trailing newlines or spaces
- Enable 'remember' to persist the key so it is not empty next session
- Confirm the provider key is active and not revoked
Example fix
// before
const key = document.querySelector('#key').value; // "sk-abc\n"
// after
const key = document.querySelector('#key').value.replace(/[\r\n]/g,'').trim(); Defensive patterns
Strategy: validation
Validate before calling
const key=(input.key||'').trim();
if(input.channel==='external' && (!key || /[\r\n]/.test(key))) throw new Error('请在设置中填写有效 API Key'); Type guard
function hasValidKey(cfg){return typeof cfg?.key==='string' && cfg.key.trim().length>0 && !/[\r\n]/.test(cfg.key);} Try / catch
try{ cfg=apiConfig(input); }catch(e){ if(e.message.includes('API Key')) showKeyInputError(); } Prevention
- Paste keys via a single-line input; strip newlines programmatically
- Enable 'remember' to persist the key
- Rotate/verify keys in the provider dashboard
When it happens
Trigger: apiConfig with channel='external' and input.key empty after trim, or containing \r or \n characters.
Common situations: User forgot to fill the API Key field; pasted a key with a trailing newline from clipboard; key stored from a multi-line paste; remember=false so the key was not persisted and is empty on next run.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/ba28c3f0f9e91552.
Report an issue: GitHub.
Appendix: source
Thrown at tools/conversation-canvas/public/canvas.user.js:635
}
}
// OpenAI-compatible Chat Completions. Never persist credentials in tree checkpoints.
function apiEndpoint(raw){
let url;try{url=new URL(String(raw).trim());}catch{throw Error('请输入完整的 HTTPS API 地址');}
if(url.protocol!=='https:'||url.username||url.password||url.search||url.hash)throw Error('API 地址须使用 HTTPS,且不含账号、密码、查询参数或片段');
const path=url.pathname.replace(/\/+$/,'');
url.pathname=path.endsWith('/chat/completions')?path:(path||'/v1')+'/chat/completions';
return url.href;
}
function apiConfig(input){
const channel=input?.channel==='external'?'external':'native';
const value={channel,baseUrl:String(input?.baseUrl||'').trim(),model:String(input?.model||'').trim(),key:String(input?.key||'').trim(),remember:input?.remember===true,speed:input?.speed==='provider'?'provider':'fast',revision:input?.revision||crypto.randomUUID()};
if(channel==='external'){
value.endpoint=apiEndpoint(value.baseUrl);
if(!value.model||value.model.length>200)throw Error('请填写 API 的模型名称');
if(!value.key||/[\r\n]/.test(value.key))throw Error('请在设置中填写有效 API Key');
}
return value;
}
function storedApiConfig(config){
const {channel,baseUrl,model,remember,speed,revision}=config;
return {channel,baseUrl,model,remember,speed,revision,...remember?{key:config.key}:{}};
}
function apiError(error){
if(error?.name==='AbortError')return error;
if(error?.canvasApiLocal===true)return error;
const code=Number(error?.status??error?.responseStatus);
const hint={401:'密钥无效或已过期',403:'接口拒绝访问,请检查权限',404:'地址或模型不存在',408:'接口请求超时',413:'本批资料超过接口大小限制',429:'接口限流或额度不足'}[code];
// Provider messages can echo request contents and Authorization; never display them.
return Object.assign(Error(hint?`API ${code}:${hint}`:code>=400?`API 请求失败(HTTP ${code}),请检查服务状态`:'API 连接失败,请检查地址、网络及服务状态'),{retryable:!code||code===408||code===429||code>=500});
}
View on GitHub (pinned to b1ed92e5e4)