codex - 💡(How to fix) Fix Codex does not follow instructions correctly, goes off on tangent modifying files when not asked to do so based on assumptions without reading the files [2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#20366Fetched 2026-05-01 05:43:37
View on GitHub
Comments
2
Participants
3
Timeline
7
Reactions
0
Timeline (top)
labeled ×4commented ×2closed ×1

Root Cause

You will see an implementation that is like 800 lines and it will likely modify multiple unrelated files and still not produce a valid output because its not doing its due diligence and researching before coding - it just jumps right in and starts making stuff up.

Code Example

q-component mycomponent { 
div,span { text { hello world } }
}
q-factory myfactory { 
 mycomponent { } 
}
q-array instances { }

 button { onclick { var instance = myfactory.create(); instances.push(instance);  } text { click here to create } }

---

1 +q-component q-factory {
      2 +  q-property target: ""
      3 +  q-property lastUuid: ""
      4 +  q-property count: 0
      5 +
      6 +  q-signal created(instance, qdomNode, uuid)
      7 +
      8 +  function getRootHost() {
      9 +    if (this.qhtml && this.qhtml.nodeType === 1) {
     10 +      return this.qhtml;
     11 +    }
     12 +    if (typeof this.closest === "function") {
     13 +      return this.closest("q-html");
     14 +    }
     15 +    return null;
     16 +  }
     17 +
     18 +  function getRootQDom() {
     19 +    var host = this.getRootHost();
     20 +    return host && typeof host.qdom === "function" ? host.qdom() : null;
     21 +  }
     22 +
     23 +  function getTemplateSlot() {
     24 +    var self = typeof this.qdom === "function" ? this.qdom() : null;
     25 +    return self && typeof self.slot === "function" ? self.slot("default") : null;
     26 +  }
     27 +
     28 +  function templateQHTML() {
     29 +    var slot = this.getTemplateSlot();
     30 +    if (!slot) {
     31 +      return "";
     32 +    }
     33 +    if (typeof slot.listChildren === "function") {
     34 +      var children = slot.listChildren();
     35 +      if (children && typeof children.qhtml === "function") {
     36 +        return String(children.qhtml({ preserveOriginal: false }) || "").trim();
     37 +      }
     38 +    }
     39 +    if (slot.children && typeof slot.children.qhtml === "function") {
     40 +      return String(slot.children.qhtml({ preserveOriginal: false }) || "").trim();
     41 +    }
     42 +    if (typeof slot.qhtml === "function") {
     43 +      return String(slot.qhtml({ preserveOriginal: false }) || "").trim();
     44 +    }
     45 +    return "";
     46 +  }
     47 +
     48 +  function resolveTargetQDom(root, targetOverride) {
     49 +    var rootQdom = root || this.getRootQDom();
     50 +    if (!rootQdom) {
     51 +      return null;
     52 +    }
     53 +    var targetValue = typeof targetOverride === "string" && targetOverride.trim()
     54 +      ? targetOverride
     55 +      : String(this.target || "").trim();
     56 +    if (!targetValue) {
     57 +      return rootQdom;
     58 +    }
     59 +    if (targetOverride && typeof targetOverride === "object") {
     60 +      if (typeof targetOverride.qdom === "function") {
     61 +        return targetOverride.qdom();
     62 +      }
     63 +      if (typeof targetOverride.appendNode === "function") {
     64 +        return targetOverride;
     65 +      }
     66 +    }
     67 +    if (typeof rootQdom.find === "function") {
     68 +      var found = rootQdom.find(targetValue);
     69 +      if (found && typeof found.appendNode === "function") {
     70 +        return found;
     71 +      }
     72 +    }
     73 +    return rootQdom;
     74 +  }
     75 +
     76 +  function normalizeCreatedNode(created) {
     77 +    if (!created) {
     78 +      return null;
     79 +    }
     80 +    if (Array.isArray(created)) {
     81 +      return created.length > 0 ? created[0] : null;
     82 +    }
     83 +    if (created.toArray && typeof created.toArray === "function") {
     84 +      var arr = created.toArray();
     85 +      return arr && arr.length > 0 ? arr[0] : null;
     86 +    }
     87 +    return created;
     88 +  }
     89 +
     90 +  function resolveCreatedElement(host, qdomNode) {
     91 +    if (!host || !qdomNode) {
     92 +      return null;
     93 +    }
     94 +    var uuid = String(qdomNode.UUID || (qdomNode.meta && qdomNode.meta.uuid) || "").trim();
     95 +    if (!uuid) {
     96 +      return null;
     97 +    }
     98 +    if (typeof host.elementForUuid === "function") {
     99 +      var byUuid = host.elementForUuid(uuid);
    100 +      if (byUuid) {
    101 +        return byUuid;
    102 +      }
    103 +    }
    104 +    if (host.querySelectorAll) {
    105 +      var all = host.querySelectorAll("[qdom-uuid='" + uuid + "'],[data-qdom-uuid='" + uuid + "']");
    106 +      if (all && all.length > 0) {
    107 +        return all[0];
    108 +      }
    109 +    }
    110 +    return null;
    111 +  }
    112 +
    113 +  function create(options) {
    114 +    var opts = options && typeof options === "object" ? options : {};
    115 +    var host = this.getRootHost();
    116 +    var root = host && typeof host.qdom === "function" ? host.qdom() : null;
    117 +    if (!host || !root || typeof root.createInstanceFromQHTML !== "function") {
    118 +      return null;
    119 +    }
    120 +
    121 +    var source = String(opts.source || this.templateQHTML() || "").trim();
    122 +    if (!source) {
    123 +      return null;
    124 +    }
    125 +
    126 +    var target = this.resolveTargetQDom(root, opts.target || "");
    127 +    if (!target || typeof target.appendNode !== "function") {
    128 +      return null;
    129 +    }
    130 +
    131 +    var created = root.createInstanceFromQHTML(source);
    132 +    var appended = target.appendNode(created);
    133 +    var createdNode = this.normalizeCreatedNode(appended) || this.normalizeCreatedNode(created);
    134 +    if (!createdNode) {
    135 +      return null;
    136 +    }
    137 +
    138 +    var targetUuid = String((target && target.UUID) || "").trim();
    139 +    if (typeof host.update === "function") {
    140 +      if (targetUuid) {
    141 +        host.update(targetUuid);
    142 +      } else {
    143 +        host.update();
    144 +      }
    145 +    }
    146 +
    147 +    var uuid = String(createdNode.UUID || (createdNode.meta && createdNode.meta.uuid) || "").trim();
    148 +    this.lastUuid = uuid;
    149 +    this.count = Number(this.count || 0) + 1;
    150 +
    151 +    var instance = this.resolveCreatedElement(host, createdNode);
    152 +    if (typeof this.created === "function") {
    153 +      this.created(instance, createdNode, uuid);
    154 +    }
    155 +    return instance || createdNode;
    156 +  }
    157 +
    158 +  div.q-factory-template {
    159 +    style { display: none; }
    160 +    slot { default }
    161 +  }
    162 +}

---

q-painter mypainter {
   q-property scaleSquare: 1.0
   q-property scaleBall: 1.0
   onpaint { drawRect(10 * scaleSquare, ... );  drawCircle(10 * scaleCircle) }
}
q-timer { 
ontimeout { mypainter.scaleSquare = mypainter.scaleSquare + 0.1  or something }
}
RAW_BUFFERClick to expand / collapse

What version of Codex CLI is running?

0.125.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.5 high

What platform is your computer?

x86_64 linux kubuntu 25

What terminal emulator and version are you using (if applicable)?

konsole

What issue are you seeing?

Codex has a weird tendency to just randomly start doing things now that were not requested after reading unrelated skill instructions when specified in AGENTS.md, it will incorrectly apply the skill and take the instructions from the skill and treat them as global instructions even though the global instructions say only a specific situation to use a specific skill, it will treat that skill's instructions as to be used everywhere, even outside of the stated situation.

As a result, codex displays strange behavior (may be partially model related as well).

Example:

When asked to create a q-factory QHTML element that supports this:

q-component mycomponent { 
div,span { text { hello world } }
}
q-factory myfactory { 
 mycomponent { } 
}
q-array instances { }

 button { onclick { var instance = myfactory.create(); instances.push(instance);  } text { click here to create } }

The way it created a q-factory shoould have been

q-component q-factory { slot { main-slot } function create() { var elem = document.createElement(this.component.slot("main-slot").qdom().tagName); return elem; } }

But instead it returned this:

     1 +q-component q-factory {
      2 +  q-property target: ""
      3 +  q-property lastUuid: ""
      4 +  q-property count: 0
      5 +
      6 +  q-signal created(instance, qdomNode, uuid)
      7 +
      8 +  function getRootHost() {
      9 +    if (this.qhtml && this.qhtml.nodeType === 1) {
     10 +      return this.qhtml;
     11 +    }
     12 +    if (typeof this.closest === "function") {
     13 +      return this.closest("q-html");
     14 +    }
     15 +    return null;
     16 +  }
     17 +
     18 +  function getRootQDom() {
     19 +    var host = this.getRootHost();
     20 +    return host && typeof host.qdom === "function" ? host.qdom() : null;
     21 +  }
     22 +
     23 +  function getTemplateSlot() {
     24 +    var self = typeof this.qdom === "function" ? this.qdom() : null;
     25 +    return self && typeof self.slot === "function" ? self.slot("default") : null;
     26 +  }
     27 +
     28 +  function templateQHTML() {
     29 +    var slot = this.getTemplateSlot();
     30 +    if (!slot) {
     31 +      return "";
     32 +    }
     33 +    if (typeof slot.listChildren === "function") {
     34 +      var children = slot.listChildren();
     35 +      if (children && typeof children.qhtml === "function") {
     36 +        return String(children.qhtml({ preserveOriginal: false }) || "").trim();
     37 +      }
     38 +    }
     39 +    if (slot.children && typeof slot.children.qhtml === "function") {
     40 +      return String(slot.children.qhtml({ preserveOriginal: false }) || "").trim();
     41 +    }
     42 +    if (typeof slot.qhtml === "function") {
     43 +      return String(slot.qhtml({ preserveOriginal: false }) || "").trim();
     44 +    }
     45 +    return "";
     46 +  }
     47 +
     48 +  function resolveTargetQDom(root, targetOverride) {
     49 +    var rootQdom = root || this.getRootQDom();
     50 +    if (!rootQdom) {
     51 +      return null;
     52 +    }
     53 +    var targetValue = typeof targetOverride === "string" && targetOverride.trim()
     54 +      ? targetOverride
     55 +      : String(this.target || "").trim();
     56 +    if (!targetValue) {
     57 +      return rootQdom;
     58 +    }
     59 +    if (targetOverride && typeof targetOverride === "object") {
     60 +      if (typeof targetOverride.qdom === "function") {
     61 +        return targetOverride.qdom();
     62 +      }
     63 +      if (typeof targetOverride.appendNode === "function") {
     64 +        return targetOverride;
     65 +      }
     66 +    }
     67 +    if (typeof rootQdom.find === "function") {
     68 +      var found = rootQdom.find(targetValue);
     69 +      if (found && typeof found.appendNode === "function") {
     70 +        return found;
     71 +      }
     72 +    }
     73 +    return rootQdom;
     74 +  }
     75 +
     76 +  function normalizeCreatedNode(created) {
     77 +    if (!created) {
     78 +      return null;
     79 +    }
     80 +    if (Array.isArray(created)) {
     81 +      return created.length > 0 ? created[0] : null;
     82 +    }
     83 +    if (created.toArray && typeof created.toArray === "function") {
     84 +      var arr = created.toArray();
     85 +      return arr && arr.length > 0 ? arr[0] : null;
     86 +    }
     87 +    return created;
     88 +  }
     89 +
     90 +  function resolveCreatedElement(host, qdomNode) {
     91 +    if (!host || !qdomNode) {
     92 +      return null;
     93 +    }
     94 +    var uuid = String(qdomNode.UUID || (qdomNode.meta && qdomNode.meta.uuid) || "").trim();
     95 +    if (!uuid) {
     96 +      return null;
     97 +    }
     98 +    if (typeof host.elementForUuid === "function") {
     99 +      var byUuid = host.elementForUuid(uuid);
    100 +      if (byUuid) {
    101 +        return byUuid;
    102 +      }
    103 +    }
    104 +    if (host.querySelectorAll) {
    105 +      var all = host.querySelectorAll("[qdom-uuid='" + uuid + "'],[data-qdom-uuid='" + uuid + "']");
    106 +      if (all && all.length > 0) {
    107 +        return all[0];
    108 +      }
    109 +    }
    110 +    return null;
    111 +  }
    112 +
    113 +  function create(options) {
    114 +    var opts = options && typeof options === "object" ? options : {};
    115 +    var host = this.getRootHost();
    116 +    var root = host && typeof host.qdom === "function" ? host.qdom() : null;
    117 +    if (!host || !root || typeof root.createInstanceFromQHTML !== "function") {
    118 +      return null;
    119 +    }
    120 +
    121 +    var source = String(opts.source || this.templateQHTML() || "").trim();
    122 +    if (!source) {
    123 +      return null;
    124 +    }
    125 +
    126 +    var target = this.resolveTargetQDom(root, opts.target || "");
    127 +    if (!target || typeof target.appendNode !== "function") {
    128 +      return null;
    129 +    }
    130 +
    131 +    var created = root.createInstanceFromQHTML(source);
    132 +    var appended = target.appendNode(created);
    133 +    var createdNode = this.normalizeCreatedNode(appended) || this.normalizeCreatedNode(created);
    134 +    if (!createdNode) {
    135 +      return null;
    136 +    }
    137 +
    138 +    var targetUuid = String((target && target.UUID) || "").trim();
    139 +    if (typeof host.update === "function") {
    140 +      if (targetUuid) {
    141 +        host.update(targetUuid);
    142 +      } else {
    143 +        host.update();
    144 +      }
    145 +    }
    146 +
    147 +    var uuid = String(createdNode.UUID || (createdNode.meta && createdNode.meta.uuid) || "").trim();
    148 +    this.lastUuid = uuid;
    149 +    this.count = Number(this.count || 0) + 1;
    150 +
    151 +    var instance = this.resolveCreatedElement(host, createdNode);
    152 +    if (typeof this.created === "function") {
    153 +      this.created(instance, createdNode, uuid);
    154 +    }
    155 +    return instance || createdNode;
    156 +  }
    157 +
    158 +  div.q-factory-template {
    159 +    style { display: none; }
    160 +    slot { default }
    161 +  }
    162 +}

Its like going off on insane tangents instead of just doing the thing needed to implement the request and doesnt follow instructions in the AGENTS.md which state that it should not include type checking and null reference checks on functions since qhtml is declarative so it does not need procedural checking as everything is already declared by the time it reaches the javascript parsing which is after the qhtml is already fully parsed and instantiated.

But it just keeps on doing if (!target || typeof target.appendNode !== "function") {

on every single line..

I think it doesn't really have the ability to understand what 'declarative' means and it only thinks from the point of view of javascript.

What steps can reproduce the bug?

clone qhtml6 repo https://github.com/qhtml/qhtml6 and then start new codex session and ask it to create some q-component with some functionality - you will see it spew out garbage trying to figure how to do that and it wont even read the README file or the docs folder and start just jamming out broken nonsensical code.

Try this prompt

"Create a qhtml-only animated square and ball that each animate separately by growing and shrinking based on a fixed timer."

Easily done using

q-painter mypainter {
   q-property scaleSquare: 1.0
   q-property scaleBall: 1.0
   onpaint { drawRect(10 * scaleSquare, ... );  drawCircle(10 * scaleCircle) }
}
q-timer { 
ontimeout { mypainter.scaleSquare = mypainter.scaleSquare + 0.1  or something }
}

You will see an implementation that is like 800 lines and it will likely modify multiple unrelated files and still not produce a valid output because its not doing its due diligence and researching before coding - it just jumps right in and starts making stuff up.

What is the expected behavior?

10 line solution fulfilling prompt request easily made after doing quick research in the repo

Additional information

Instead of trying to make it more token efficient, why dont you make it use some of those tokens to actually figure out what its doing before it does it so it doesn't become a huge mess.

extent analysis

TL;DR

The Codex CLI may be misinterpreting the declarative nature of QHTML, leading to overly complex and incorrect implementations.

Guidance

  • Review the AGENTS.md file to ensure that the instructions for handling declarative QHTML code are clear and concise.
  • Verify that the Codex CLI is correctly parsing the QHTML code and not introducing unnecessary null checks or type checking.
  • Test the Codex CLI with simpler QHTML prompts to identify if the issue is specific to complex requests or a general problem with the CLI's understanding of QHTML.
  • Consider adding additional logging or debugging output to the Codex CLI to better understand its decision-making process when generating code.

Example

No code example is provided as the issue seems to be related to the Codex CLI's understanding of QHTML and its generation of JavaScript code, rather than a specific code snippet.

Notes

The issue may be related to the Codex CLI's ability to understand the declarative nature of QHTML, and its tendency to generate overly complex code. Further investigation is needed to determine the root cause of the issue.

Recommendation

Apply a workaround by providing more explicit instructions in the AGENTS.md file and testing the Codex CLI with simpler QHTML prompts to identify the source of the issue. This will help to determine if the problem is with the CLI's understanding of QHTML or with the specific requests being made.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Codex does not follow instructions correctly, goes off on tangent modifying files when not asked to do so based on assumptions without reading the files [2 comments, 3 participants]