{"record":{"id":"b30ae4f4dc5bdc7c","repo":"YMFE/yapi","slug":"context-hostname","errorCode":null,"errorMessage":"context.hostname 不能被赋值","messagePattern":"context\\.hostname 不能被赋值","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/postmanLib.js","lineNumber":266,"sourceCode":"async function crossRequest(defaultOptions, preScript, afterScript, commonContext = {}) {\n  let options = Object.assign({}, defaultOptions);\n  const taskId = options.taskId || Math.random() + '';\n  let urlObj = URL.parse(options.url, true),\n    query = {};\n  query = Object.assign(query, urlObj.query);\n  let context = {\n    isNode,\n    get href() {\n      return urlObj.href;\n    },\n    set href(val) {\n      throw new Error('context.href 不能被赋值');\n    },\n    get hostname() {\n      return urlObj.hostname;\n    },\n    set hostname(val) {\n      throw new Error('context.hostname 不能被赋值');\n    },\n\n    get caseId() {\n      return options.caseId;\n    },\n\n    set caseId(val) {\n      throw new Error('context.caseId 不能被赋值');\n    },\n\n    method: options.method,\n    pathname: urlObj.pathname,\n    query: query,\n    requestHeader: options.headers || {},\n    requestBody: options.data,\n    promise: false,\n    storage: await getStorage(taskId)\n  };","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/YMFE/yapi/blob/59bade3a8a43e7db077d38a4b0c7c584f30ddf8c/common/postmanLib.js#L248-L284","documentation":"context.hostname in the test-script sandbox is a read-only getter derived from the request URL. The setter exists solely to throw, preventing scripts from mutating the resolved host.","triggerScenarios":"A case script executes context.hostname = 'api.example.com' during test/assert execution.","commonSituations":"Attempting to switch environments from inside a script; copying Postman snippets that mutate context; misunderstand that sandbox context is read-only.","solutions":["Delete the hostname assignment from the script","Change the request URL/environment at the case level instead of in the script","Only read context.hostname in scripts"],"exampleFix":"// before\ncontext.hostname = 'staging.api.com';\n// after\n// configure environment host in the case, then read it\nconst host = context.hostname;","handlingStrategy":"type-guard","validationCode":"if (context.hostname !== expectedHost) console.warn('unexpected host; reconfigure environment instead of assigning');","typeGuard":"function isReadOnlyCtxProp(obj, key){ const d = Object.getOwnPropertyDescriptor(obj, key); return !!d && d.get && d.set && d.set.toString().includes('throw'); }","tryCatchPattern":"try {\n  context.hostname = host;\n} catch (e) {\n  console.warn('hostname is derived from request URL and cannot be set');\n}","preventionTips":["Never assign to context.* properties in scripts","Switch hosts via YApi environments, not scripts","Audit scripts for '=' assignments on context","Use getters for reads only"],"tags":["script-sandbox","immutable-context","postman-lib"],"backgroundTag":"readonly-property-assignment","analyzedSha":"59bade3a8a43e7db077d38a4b0c7c584f30ddf8c","analyzedAt":"2026-08-29T08:45:22.203Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}