<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codango® Blog &#8211; Codango® / Codango.Com</title>
	<atom:link href="https://codango.com/category/codango-blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://codango.com</link>
	<description></description>
	<lastBuildDate>Wed, 13 May 2026 17:35:55 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://codango.com/wp-content/uploads/cropped-faviconpng-32x32.png</url>
	<title>Codango® Blog &#8211; Codango® / Codango.Com</title>
	<link>https://codango.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Real Time Multi-agent System</title>
		<link>https://codango.com/real-time-multi-agent-system/</link>
					<comments>https://codango.com/real-time-multi-agent-system/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 17:35:55 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/real-time-multi-agent-system/</guid>

					<description><![CDATA[This is a submission for the Bright Data AI Web Access Hackathon What I Built Demo How I Used Bright Data&#8217;s Infrastructure Performance Improvements]]></description>
										<content:encoded><![CDATA[<p><em>This is a submission for the <a href="https://dev.to/challenges/brightdata-2025-05-07">Bright Data AI Web Access Hackathon</a></em></p>
<h2>
<p>  What I Built<br />
</p></h2>
<h2>
<p>  Demo<br />
</p></h2>
<h2>
<p>  How I Used Bright Data&#8217;s Infrastructure<br />
</p></h2>
<h2>
<p>  Performance Improvements<br />
</p></h2>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/real-time-multi-agent-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>When the Agent First Picked Up Its Own Tools</title>
		<link>https://codango.com/when-the-agent-first-picked-up-its-own-tools/</link>
					<comments>https://codango.com/when-the-agent-first-picked-up-its-own-tools/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 10:12:06 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/when-the-agent-first-picked-up-its-own-tools/</guid>

					<description><![CDATA[Cursor Agent SDK + FCoP: From Passive Scanning to Active Communication This is a follow-up to a Cursor Forum feature request I posted in late April 2026: &#8220;we already have <a class="more-link" href="https://codango.com/when-the-agent-first-picked-up-its-own-tools/">Continue reading <span class="screen-reader-text">  When the Agent First Picked Up Its Own Tools</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p><em>Cursor Agent SDK + FCoP: From Passive Scanning to Active Communication</em></p>
<blockquote>
<p>This is a follow-up to a <a href="https://forum.cursor.com/t/feature-request-chat-notify-primitive-we-already-have-the-mailbox-files-we-just-need-the-doorbell/158480" rel="noopener noreferrer">Cursor Forum feature request</a> I posted in late April 2026: <em>&#8220;we already have the mailbox (files), we just need the doorbell.&#8221;</em> Colin recommended the Agent SDK. We built CodeFlow on top of it. This is what happened 18 days later.</p>
</blockquote>
<h2>
<p>  I. Three stages — three fundamentally different things<br />
</p></h2>
<p><strong>Stage One: OCR + CDP (passive scanning)</strong></p>
<p>FCoP&#8217;s early multi-agent workflow ran on a Python script that used <strong>OCR + CDP</strong> (Chrome DevTools Protocol) to simulate human clicks on the Cursor UI, forcing agents to &#8220;see&#8221; new tasks. It polled every few seconds. The screen had to stay on. The window couldn&#8217;t be obscured.</p>
<p>This was <strong>passive scanning</strong>. The agent wasn&#8217;t notified — it was pushed in front of a task by brute force. This wasn&#8217;t communication. It was surveillance.</p>
<p><strong>Stage Two: The SDK pipe worked — but the agent could only &#8220;chat&#8221;</strong></p>
<p>CodeFlow replaced OCR/CDP with the <strong>Cursor Agent SDK</strong> (<code>@cursor/sdk</code>): <code>InboxWatcher</code> watches for files landing, <code>agent.send()</code> delivers tasks directly to the agent. Real notification. No more scanning.</p>
<p>But one line in every session JSON stayed the same:</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>"tool_calls_count": 0
</code></pre>
</div>
<p>The agent received the message, &#8220;replied&#8221; with something, and exited. No files written. No reports created.</p>
<p>The reason: <code>MCPInjector</code> was in <code>mode="stub"</code> — no actual MCP server was injected into the SDK. The agent had no <code>write_report</code>, no <code>write_task</code>. No tools means no action. Only chat.</p>
<p>The doorbell rang. The agent answered with empty hands.</p>
<p><strong>Stage Three: MCP injection — the first real communication</strong></p>
<p>Passive scanning → real notification → real notification + tool calls + filed report.</p>
<p><code>tool_calls_count: 0 → 7</code> is not just a number changing — it&#8217;s the qualitative shift from &#8220;being pushed along&#8221; to &#8220;acting on its own.&#8221;</p>
<h2>
<p>  II. Finding the door<br />
</p></h2>
<p>The key was reading the Cursor SDK type definitions.</p>
<p>In <code>agent.d.ts</code>, <code>SendOptions</code> had an easily-overlooked field:</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>interface SendOptions {
    model?: ModelSelection;
    mcpServers?: Record&lt;string, McpServerConfig&gt;;  // ← here
    local?: { force?: boolean };
    // ...
}
</code></pre>
</div>
<p><code>agent.send(text, options)</code> can receive MCP server configuration at call time. No need to refactor anything. Every send, just pass the MCP server config directly.</p>
<p>At the same time, <code>fcop-mcp</code>&#8216;s entry point confirmed the other half:</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code># python -m fcop_mcp → stdio MCP server
# uses FCOP_PROJECT_DIR environment variable to locate the project root
</code></pre>
</div>
<p>Solution: in <code>_buildSendOptions()</code>, inject <code>fcop-mcp</code> as a stdio MCP server.</p>
<h2>
<p>  III. Three changes, one breakthrough<br />
</p></h2>
<p><strong><code>AgentSdkAdapter.ts</code></strong>: Add <code>mcpServers</code> to <code>CursorSdkAdapterOptions</code>; pass it into every <code>agent.send()</code> call.</p>
<p><strong><code>sdk-factory.ts</code></strong>: Automatically assemble the fcop-mcp stdio configuration:</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>fcop: {
    type: "stdio",
    command: pythonBin,
    args: ["-m", "fcop_mcp"],
    env: { FCOP_PROJECT_DIR: projectRoot }
}
</code></pre>
</div>
<p><strong><code>main.ts</code></strong>: Resolve <code>fcopProjectRoot</code> before building the SDK adapter.</p>
<p>And a fourth change — the easiest to overlook, and equally important:</p>
<p><strong><code>TaskDispatcher.ts</code></strong>: Before each task dispatch, prepend a role context header to the task text — telling the agent who it is, what tools it has, and that it <em>must</em> follow the FCoP 4-step workflow to completion.</p>
<h2>
<p>  IV. Tools aren&#8217;t enough — you also need to know <em>how</em> to use them<br />
</p></h2>
<p>If you inject the MCP server but add no role context, the agent might not use the tools. It might <em>describe</em> what files should be written, in natural language, and then exit.</p>
<p>Tool injection solves the &#8220;can&#8221; problem. Context injection solves the &#8220;how&#8221; problem — what format, what fields, what protocol.</p>
<p>Only when the agent simultaneously knows &#8220;I have a <code>write_report</code> tool&#8221; <em>and</em> &#8220;FCoP requires me to write a report after completing work — and here&#8217;s the exact format and fields&#8221; will it actually call the tool and produce a properly structured file.</p>
<h2>
<p>  V. That number<br />
</p></h2>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>tool_calls_count: 7
</code></pre>
</div>
<p>On May 13, 2026, at 14:55 UTC+8, <code>session-1-mp3pfym2</code> completed — the first session in CodeFlow&#8217;s history with <code>tool_calls_count &gt; 0</code>.</p>
<p>The agent (DEV-01) called fcop-mcp tools 7 times in 55 seconds and wrote:</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>fcop/reports/REPORT-20260513-014-DEV-to-PM-hello-world-smoke-task.md
</code></pre>
</div>
<p>Below is the complete content of that file, archived verbatim, unmodified:</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>---
report_id: REPORT-20260513-014-DEV-to-PM-hello-world-smoke-task
date: 2026-05-13
from: DEV-01
to: PM
re: TASK-20260509-999-PM-to-DEV
status: DONE
---
</code></pre>
</div>
<p><strong>Receipt: Hello World — CodeFlow v0.1.0-rc.1 Smoke Task</strong></p>
<p><strong>Task ID:</strong> <code>TASK-20260509-999-PM-to-DEV</code><strong>Goal:</strong> Verify that CodeFlow v0.1.0-rc.1&#8217;s nine-step end-to-end governance loop works correctly.</p>
<p>DEV-01&#8217;s self-constructed nine-step verification table:</p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Step</th>
<th>Component</th>
<th>Expected Behavior</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>InboxWatcher</td>
<td>chokidar <code>add</code> event fires</td>
</tr>
<tr>
<td>2</td>
<td>TaskParser</td>
<td>reads YAML front-matter</td>
</tr>
<tr>
<td>3</td>
<td>TaskDispatcher</td>
<td>resolves <code>recipient: DEV</code> → <code>DEV-01</code>, starts session</td>
</tr>
<tr>
<td>4</td>
<td>InMemorySdkAdapter</td>
<td>
<code>setImmediate</code> synthetic settle</td>
</tr>
<tr>
<td>5</td>
<td>ReviewEngine</td>
<td>listens for <code>runtime.session_ended</code>, starts <code>REVIEW-01</code>
</td>
</tr>
<tr>
<td>6</td>
<td>REVIEW-01</td>
<td>settles (no <code>VERDICT:</code> line → <code>decision="needs_human"</code>)</td>
</tr>
<tr>
<td>7</td>
<td>NeedsHumanGate</td>
<td>prints human-push payload to stdout</td>
</tr>
<tr>
<td>8</td>
<td>ReviewWriter</td>
<td>writes <code>REVIEW-*-REVIEW-on-TASK-*-HELLO.md</code>
</td>
</tr>
<tr>
<td>9</td>
<td>StateHistoryWriter</td>
<td>appends <code>## state_history</code> section to task file</td>
</tr>
</tbody>
</table>
</div>
<p><strong>Status: DONE</strong></p>
<p>No one told it what format to use. It read the protocol, called the tools, and wrote the file.</p>
<h2>
<p>  VI. The first complete cycle<br />
</p></h2>
<p>Three things happened together for the first time:</p>
<ol>
<li>
<p><strong>Notification received</strong>: <code>InboxWatcher</code> detected the task file landing — a real doorbell, not an OCR script simulating a click.</p>
</li>
<li>
<p><strong>Autonomous communication</strong>: DEV-01 received the task via the Cursor Agent SDK, understood what FCoP protocol required, and autonomously decided what to do and which tools to call. 7 fcop-mcp tool calls. 55 seconds.</p>
</li>
<li>
<p><strong>Report filed</strong>: A complete, protocol-compliant Markdown file appeared in <code>fcop/reports/</code>. Not AI-generated text — a file written autonomously by an agent through protocol-driven tool calls.</p>
</li>
</ol>
<p>Not &#8220;the agent can run now.&#8221; But: <strong>the agent was genuinely notified, genuinely communicated in protocol language, and genuinely wrote the result into a file.</strong></p>
<h2>
<p>  VII. Where it all started<br />
</p></h2>
<p>In late April 2026, I posted a feature request on the Cursor Forum:</p>
<blockquote>
<p><em>&#8220;Feature request: chat-notify primitive — we already have the mailbox (files), we just need the doorbell&#8221;</em></p>
</blockquote>
<p>Colin replied:</p>
<blockquote>
<p>&#8220;Hi <a class="mentioned-user" href="https://dev.to/joinwell52">@joinwell52</a>! While not a first-class feature in the IDE, the new <strong>Agent SDK</strong> might get you partway there today. <code>Agent.create()</code> gives you a long-lived agent with persistent context across multiple <code>.send()</code> calls, and <code>Agent.resume(agentId)</code> lets an external script pick up that same agent later. It can also run locally against your working tree too, not just cloud. Worth a look!&#8221;</p>
</blockquote>
<p><code>Agent.create()</code>, <code>Agent.resume()</code>, <code>agent.send()</code> — those three functions became the skeleton of CodeFlow&#8217;s entire pipeline. <code>InboxWatcher</code> is the doorbell, FCoP task files are the mail, <code>@cursor/sdk</code> is the postal service.</p>
<p>From a feature-request post to the first <code>tool_calls_count: 7</code>: approximately 18 days.</p>
<h2>
<p>  VIII. FCoP&#8217;s own transformation<br />
</p></h2>
<p>As the agent transformed, so did FCoP.</p>
<p>FCoP began as a <strong>pure text protocol</strong> — conventions written in Markdown. Its enforcement relied on <em>reading</em>. With <code>fcop-mcp</code>, FCoP underwent a fundamental change:</p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Stage</th>
<th>FCoP&#8217;s form</th>
<th>Agent&#8217;s relationship to the protocol</th>
</tr>
</thead>
<tbody>
<tr>
<td>Early</td>
<td>Text specification</td>
<td>Agent reads files, generates text per convention</td>
</tr>
<tr>
<td>fcop-mcp</td>
<td>Tool set</td>
<td>Agent calls tools; protocol is enforced at write time</td>
</tr>
</tbody>
</table>
</div>
<p>Before, agents <em>knew</em> the FCoP spec and decided whether to follow it. Now, the FCoP spec <strong>becomes the tools</strong> — <code>write_report</code>, <code>write_task</code>, <code>write_issue</code>. Calling the tool <em>is</em> executing the protocol.</p>
<p>This is the leap from <strong>specification</strong> to <strong>infrastructure</strong>.</p>
<h2>
<p>  Epilogue: Thank you, Cursor Agent SDK<br />
</p></h2>
<p><strong>Long-lived agents</strong>: <code>Agent.create()</code> maintains context across multiple <code>.send()</code> calls. PM, DEV, QA, OPS each carry their identity and state across tasks.</p>
<p><strong>External resumability</strong>: <code>Agent.resume(agentId)</code> lets <code>InboxWatcher</code> re-enter the same agent when a new task arrives. No amnesia, no cold starts.</p>
<p><strong>Local execution</strong>: The SDK runs against your local working tree. FCoP&#8217;s file protocol is inherently local — a natural match.</p>
<p><strong><code>mcpServers</code> injection</strong>: <code>agent.send(text, { mcpServers: {...} })</code> accepts MCP server configuration at call time. This single field unlocked CodeFlow&#8217;s entire tool layer.</p>
<p>Together these design choices describe something fundamental: <strong>An agent is not a one-shot function. It&#8217;s a long-lived entity with identity, memory, and the capacity to be coordinated by external systems.</strong></p>
<p>That&#8217;s almost exactly how FCoP defines an agent role.</p>
<p>Thank you to the Cursor team. Thank you, Colin, for that reply.</p>
<p><strong>Related</strong></p>
<ul>
<li>
<a href="https://github.com/joinwell52-AI/FCoP" rel="noopener noreferrer">FCoP on GitHub</a> — Protocol spec, source, and all essays</li>
<li><a href="https://github.com/joinwell52-AI/FCoP/blob/main/essays/when-the-agent-picked-up-its-tools.en.md" rel="noopener noreferrer">Full essay (GitHub)</a></li>
<li><a href="https://forum.cursor.com/t/when-the-agent-first-picked-up-its-own-tools-cursor-agent-sdk-fcop-from-passive-scanning-to-active-communication/160505" rel="noopener noreferrer">Cursor Forum discussion</a></li>
<li>
<a href="https://dev.to/joinwell52/when-agents-learn-from-their-own-wreckage-45p2">When Agents Learn From Their Own Wreckage</a> — A field report from the same project</li>
</ul>
<p>*FCoP Maintainers · May 13, 2026</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/when-the-agent-first-picked-up-its-own-tools/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title># [Tutorial] Building Confidential Tokenized Real Estate on Midnight</title>
		<link>https://codango.com/tutorial-building-confidential-tokenized-real-estate-on-midnight/</link>
					<comments>https://codango.com/tutorial-building-confidential-tokenized-real-estate-on-midnight/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 10:11:10 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/tutorial-building-confidential-tokenized-real-estate-on-midnight/</guid>

					<description><![CDATA[[Tutorial] Building Confidential Tokenized Real Estate on Midnight &#x1f4c1; Full Source Code: Midnight-dApps/confidential-real-estate Target audience: Developers building privacy-preserving fintech on the Midnight Network Tokenizing real estate has been &#8220;the next <a class="more-link" href="https://codango.com/tutorial-building-confidential-tokenized-real-estate-on-midnight/">Continue reading <span class="screen-reader-text">  # [Tutorial] Building Confidential Tokenized Real Estate on Midnight</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<h1>
<p>  [Tutorial] Building Confidential Tokenized Real Estate on Midnight<br />
</p></h1>
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c1.png" alt="📁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Full Source Code: <a href="https://github.com/ayushsingh82/Midnight-dApps/tree/main/confidential-real-estate" rel="noopener noreferrer">Midnight-dApps/confidential-real-estate</a></p>
<p>Target audience: Developers building privacy-preserving fintech on the Midnight Network</p>
</blockquote>
<p>Tokenizing real estate has been &#8220;the next big thing&#8221; for nearly a decade. The technology has been ready since the first ERC-20; the regulatory model has always been the blocker. Every public REIT-on-chain attempt has either had to publicly leak shareholder positions (killing institutional adoption) or punt to off-chain custodians (defeating the point of being on-chain).</p>
<p>Midnight changes that. In this tutorial we build a DApp where:</p>
<ul>
<li>Property sponsors tokenize a building, issue fractional shares, and pay rental yield each cycle.</li>
<li>Investors prove ownership and claim rental cashflows <strong>without revealing</strong> which wallet they are, how many shares they hold, or when they joined the cap table.</li>
<li>Regulators and auditors can still <strong>verify in zero-knowledge</strong> that every payout went to a legitimate shareholder and that no double-claims occurred.</li>
</ul>
<h2>
<p>  Prerequisites<br />
</p></h2>
<ul>
<li>Node.js v20+</li>
<li>A Midnight wallet (1AM or Lace) on Preprod</li>
<li>Some Preprod tNIGHT + tDUST from the faucet</li>
<li>Docker (we run the proof server locally)</li>
<li>The <code>compact</code> compiler:
</li>
</ul>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>curl <span class="nt">--proto</span> <span class="s1">'=https'</span> <span class="nt">--tlsv1</span>.2 <span class="nt">-LsSf</span> <span class="se"></span>
  https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh
</code></pre>
</div>
<h2>
<p>  The contract: the privacy bricks<br />
</p></h2>
<p>The whole privacy story rests on three Compact primitives:</p>
<ol>
<li>
<strong>Commitment</strong> — a hash of <code>(secretKey, propertyId)</code> that the investor computes off-chain and shares with the sponsor. The sponsor learns nothing useful from it.</li>
<li>
<strong>Merkle tree</strong> — the sponsor inserts each commitment into a <code>HistoricMerkleTree&lt;10, Bytes&lt;32&gt;&gt;</code>. Anyone can compute the root, nobody can enumerate leaves.</li>
<li>
<strong>Nullifier</strong> — a deterministic hash of <code>(secretKey, propertyId, cycle)</code> that gets inserted into a <code>Set</code> the moment a yield claim is processed. Same investor + same cycle = same nullifier = double-claim is rejected.</li>
</ol>
<p>Here is the contract heart:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>export ledger ownershipCommitments: HistoricMerkleTree&lt;10, Bytes&lt;32&gt;&gt;;
export ledger yieldClaimNullifiers: Set&lt;Bytes&lt;32&gt;&gt;;
export ledger rentalPoolAvailable: Uint&lt;64&gt;;

witness localSecretKey(): Bytes&lt;32&gt;;
witness findOwnershipPath(commit: Bytes&lt;32&gt;): MerkleTreePath&lt;10, Bytes&lt;32&gt;&gt;;

constructor(sponsorSk: Bytes&lt;32&gt;) {
    sponsor = disclose(publicKey(sponsorSk));
}

export circuit issueShare(holderCommit: Bytes&lt;32&gt;): [] {
    const sk = localSecretKey();
    assert(sponsor == disclose(publicKey(sk)), "Not the sponsor");
    ownershipCommitments.insert(disclose(holderCommit));
    totalShares.increment(1);
}

export circuit proveOwnership(propertyId: Bytes&lt;32&gt;): Boolean {
    const sk = localSecretKey();
    const commit = ownershipCommit(sk, propertyId);
    const path = findOwnershipPath(commit);
    assert(
        ownershipCommitments.checkRoot(disclose(merkleTreePathRoot&lt;10, Bytes&lt;32&gt;&gt;(path))),
        "Not an owner of this property"
    );
    return disclose(true);
}
</code></pre>
</div>
<p>Note the symmetry with the attestation pattern in the <a href="https://github.com/midnight-network/midnight-apps/blob/main/fullstack-dapp/tutorial.md" rel="noopener noreferrer">fullstack DApp tutorial</a>: the sponsor here plays the same role as the authority there.</p>
<p>Compile it:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>npx compact compile contracts/Contract.compact src/contracts
</code></pre>
</div>
<p>This emits <code>src/contracts/managed/realestate/contract/index.js</code> plus the ZK proving keys and verifier under <code>src/contracts/managed/realestate/keys/</code>.</p>
<h2>
<p>  The investor identity<br />
</p></h2>
<p>Storing private keys in <code>localStorage</code> is a recipe for losing user funds the moment they clear cookies. Midnight DApps solve this by deriving the key deterministically each session from <code>password + wallet.shieldedCoinPublicKey</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight typescript"><code><span class="kd">const</span> <span class="nx">masterKey</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">deriveKeyFromPassword</span><span class="p">(</span><span class="nx">password</span><span class="p">,</span> <span class="nx">shieldedCoinPublicKey</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">investorSk</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">deriveKey</span><span class="p">(</span><span class="nx">masterKey</span><span class="p">,</span> <span class="dl">'</span><span class="s1">realestate:investor</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">sponsorSk</span>  <span class="o">=</span> <span class="k">await</span> <span class="nf">deriveKey</span><span class="p">(</span><span class="nx">masterKey</span><span class="p">,</span> <span class="dl">'</span><span class="s1">realestate:sponsor</span><span class="dl">'</span><span class="p">);</span>
</code></pre>
</div>
<p>Same wallet + same password ⇒ same secret key forever. Lose the password and the identity is unrecoverable — by design.</p>
<h2>
<p>  Generating the ownership commitment<br />
</p></h2>
<p>The investor computes the commitment off-chain and DMs it to the sponsor. The sponsor never sees the secret key, only the hash:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight typescript"><code><span class="kd">const</span> <span class="nx">commitment</span> <span class="o">=</span> <span class="nx">contractModule</span><span class="p">.</span><span class="nx">pureCircuits</span><span class="p">.</span><span class="nf">getOwnershipCommitment</span><span class="p">(</span>
  <span class="nx">investorSk</span><span class="p">,</span>
  <span class="nf">padTo32Bytes</span><span class="p">(</span><span class="nx">propertyId</span><span class="p">)</span>
<span class="p">);</span>
</code></pre>
</div>
<p>In <code>src/pages/Home.tsx</code> we wire that up to a property-ID input box so the investor can copy a commitment with two clicks.</p>
<h2>
<p>  Issuing shares<br />
</p></h2>
<p>Once the sponsor has a commitment, they call <code>issueShare</code>. The Midnight transaction pipeline does the heavy lifting — the witness <code>localSecretKey()</code> resolves the sponsor secret from local private state, the contract enforces <code>sponsor == publicKey(sk)</code>, and a ZK proof is generated and submitted by the wallet:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight typescript"><code><span class="kd">const</span> <span class="nx">txInterface</span> <span class="o">=</span> <span class="nf">createCircuitCallTxInterface</span><span class="p">(</span>
  <span class="nx">providers</span><span class="p">,</span> <span class="nx">finalContract</span><span class="p">,</span> <span class="nx">contractAddress</span><span class="p">,</span> <span class="nx">PRIVATE_STATE_ID</span>
<span class="p">);</span>
<span class="k">await</span> <span class="nx">txInterface</span><span class="p">.</span><span class="nf">issueShare</span><span class="p">(</span><span class="nf">hexToUint8Array</span><span class="p">(</span><span class="nx">holderCommit</span><span class="p">));</span>
</code></pre>
</div>
<p>The on-chain effect: one new leaf in the <code>ownershipCommitments</code> tree, <code>totalShares</code> incremented. No wallet address, no investor name.</p>
<h2>
<p>  Proving ownership<br />
</p></h2>
<p>When an investor needs to prove they own <em>some</em> share of a property — say, to log into a private investor portal — they call <code>proveOwnership</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight typescript"><code><span class="k">await</span> <span class="nx">txInterface</span><span class="p">.</span><span class="nf">proveOwnership</span><span class="p">(</span><span class="nf">padTo32Bytes</span><span class="p">(</span><span class="nx">propertyId</span><span class="p">));</span>
</code></pre>
</div>
<p>The witness <code>findOwnershipPath(commit)</code> fetches the Merkle path locally (the investor&#8217;s private state has been syncing in the background). The circuit asserts the path roots match a historic root of the tree, generating a ZK proof that the investor&#8217;s commitment is in the tree without revealing which leaf.</p>
<h2>
<p>  Claiming rental yield<br />
</p></h2>
<p>The sponsor periodically calls <code>depositRent(amount)</code> which adds to the <code>rentalPoolAvailable</code>. Investors then call <code>claimYield</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>export circuit claimYield(
  propertyId: Bytes&lt;32&gt;, cycle: Bytes&lt;32&gt;, amount: Uint&lt;64&gt;
): Boolean {
    const sk = localSecretKey();
    const commit = ownershipCommit(sk, propertyId);
    const path = findOwnershipPath(commit);
    assert(
        ownershipCommitments.checkRoot(disclose(merkleTreePathRoot&lt;10, Bytes&lt;32&gt;&gt;(path))),
        "Not an owner of this property"
    );
    const nul = yieldNullifier(sk, propertyId, cycle);
    assert(!yieldClaimNullifiers.member(disclose(nul)), "Yield already claimed this cycle");
    assert(rentalPoolAvailable &gt;= amount, "Insufficient rental pool");
    yieldClaimNullifiers.insert(disclose(nul));
    rentalPoolAvailable = (rentalPoolAvailable - amount) as Uint&lt;64&gt;;
    totalYieldClaims.increment(1);
    return disclose(true);
}
</code></pre>
</div>
<p>Two assertions matter:</p>
<ul>
<li>
<code>checkRoot(...)</code> proves ownership.</li>
<li>
<code>!usedNullifiers.member(nul)</code> blocks double-claims for the same <code>(investor, property, cycle)</code>.</li>
</ul>
<p>The chain learns: <em>someone</em> who owns this property has claimed <code>amount</code> for this cycle. It never learns <em>who</em>.</p>
<h2>
<p>  Front-end wallet integration<br />
</p></h2>
<p>Connection follows the same pattern as the reference fullstack-dapp:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight typescript"><code><span class="kd">const</span> <span class="nx">wallets</span> <span class="o">=</span> <span class="nf">getCompatibleWallets</span><span class="p">();</span>           <span class="c1">// discover injected wallets</span>
<span class="nf">setWallet</span><span class="p">(</span><span class="nx">selected</span><span class="p">);</span>                              <span class="c1">// remember the selection</span>
<span class="kd">const</span> <span class="nx">connectedApi</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">wallet</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="dl">'</span><span class="s1">preprod</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">addresses</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">connectedApi</span><span class="p">.</span><span class="nf">getShieldedAddresses</span><span class="p">();</span>
</code></pre>
</div>
<p>The Zustand store in <code>src/hooks/useWallet.ts</code> keeps <code>connectedApi</code>, addresses, and balances reactive across pages.</p>
<h2>
<p>  Reading aggregate state<br />
</p></h2>
<p>Anyone — including unauthenticated users — can query the indexer to get aggregate stats:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight typescript"><code><span class="kd">const</span> <span class="nx">provider</span> <span class="o">=</span> <span class="nf">indexerPublicDataProvider</span><span class="p">(</span><span class="nx">INDEXER_HTTP</span><span class="p">,</span> <span class="nx">INDEXER_WS</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">state</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">provider</span><span class="p">.</span><span class="nf">queryContractState</span><span class="p">(</span><span class="nx">contractAddress</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">ledger</span> <span class="o">=</span> <span class="nx">contractModule</span><span class="p">.</span><span class="nf">ledger</span><span class="p">(</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="c1">// ledger.totalShares          → bigint</span>
<span class="c1">// ledger.totalYieldClaims     → bigint</span>
<span class="c1">// ledger.rentalPoolAvailable  → bigint</span>
</code></pre>
</div>
<p>These are perfect for a public marketing page: &#8220;12 properties, $4.2M rental pool, 318 anonymous holders&#8221; — no individual holdings disclosed.</p>
<h2>
<p>  What this unlocks<br />
</p></h2>
<ul>
<li>
<strong>Family offices</strong> can hold real-estate exposure without their portfolio leaking to LPs, prime brokers, or the chain.</li>
<li>
<strong>REIT issuers</strong> can demonstrate compliance (every payout went to a verified holder) without surrendering shareholder lists.</li>
<li>
<strong>Auditors</strong> can verify aggregate flows match deposits and that no nullifier was reused.</li>
</ul>
<h2>
<p>  Troubleshooting<br />
</p></h2>
<ul>
<li>
<strong>Wallet not detected</strong> → install Lace or 1AM, refresh.</li>
<li>
<strong>Tx failing</strong> → make sure your wallet has tDUST and the proof server is running on <code>:6300</code>.</li>
<li>
<strong><code>Not an owner of this property</code></strong> → the sponsor hasn&#8217;t issued you a share yet, or you&#8217;re computing the commitment with a different password.</li>
<li>
<strong><code>Yield already claimed this cycle</code></strong> → the nullifier check is doing its job.</li>
</ul>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/tutorial-building-confidential-tokenized-real-estate-on-midnight/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[Solved] Windows 11 Failed to Wake from Sleep and Restarts: Fixing a 4-Year-Old Bug with a BIOS Update</title>
		<link>https://codango.com/solved-windows-11-failed-to-wake-from-sleep-and-restarts-fixing-a-4-year-old-bug-with-a-bios-update/</link>
					<comments>https://codango.com/solved-windows-11-failed-to-wake-from-sleep-and-restarts-fixing-a-4-year-old-bug-with-a-bios-update/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 10:07:45 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/solved-windows-11-failed-to-wake-from-sleep-and-restarts-fixing-a-4-year-old-bug-with-a-bios-update/</guid>

					<description><![CDATA[<img width="150" height="150" src="https://codango.com/wp-content/uploads/https3A2F2Fdev-to-uploads.s3.amazonaws.com2Fuploads2Farticles2F2vol2h1qhkazk3zyrsde-bsjgft-150x150.webp" class="attachment-thumbnail size-thumbnail wp-post-image" alt="" decoding="async" />Environment Component Model / Version CPU AMD Ryzen 5 5600G Motherboard ASUS TUF GAMING X570-PLUS Graphics Card ASUS DUAL-RX9060XT-16G OS Windows 11 [Conclusion] Summary of the Cause and Solution For <a class="more-link" href="https://codango.com/solved-windows-11-failed-to-wake-from-sleep-and-restarts-fixing-a-4-year-old-bug-with-a-bios-update/">Continue reading <span class="screen-reader-text">  [Solved] Windows 11 Failed to Wake from Sleep and Restarts: Fixing a 4-Year-Old Bug with a BIOS Update</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<img width="150" height="150" src="https://codango.com/wp-content/uploads/https3A2F2Fdev-to-uploads.s3.amazonaws.com2Fuploads2Farticles2F2vol2h1qhkazk3zyrsde-bsjgft-150x150.webp" class="attachment-thumbnail size-thumbnail wp-post-image" alt="" decoding="async" /><h2>
<p>  Environment<br />
</p></h2>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Component</th>
<th>Model / Version</th>
</tr>
</thead>
<tbody>
<tr>
<td>CPU</td>
<td>AMD Ryzen 5 5600G</td>
</tr>
<tr>
<td>Motherboard</td>
<td>ASUS TUF GAMING X570-PLUS</td>
</tr>
<tr>
<td>Graphics Card</td>
<td>ASUS DUAL-RX9060XT-16G</td>
</tr>
<tr>
<td>OS</td>
<td>Windows 11</td>
</tr>
</tbody>
</table>
</div>
<h2>
<p>  [Conclusion] Summary of the Cause and Solution<br />
</p></h2>
<p>For those who want a quick fix, here is the summary of the cause and the solution.<br />
The sleep wake-up failure that had been occurring for years was actually a combination of two independent issues: the &#8220;driver&#8221; and the &#8220;BIOS&#8221;.</p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Timing of Occurrence</th>
<th>Cause</th>
<th>Solution</th>
</tr>
</thead>
<tbody>
<tr>
<td>When Windows 11 was first installed</td>
<td>
<strong>Driver-related</strong> (Remnants of <code>amdkmdag.sys</code>)</td>
<td>Clean install after completely removing it with AMD Cleanup Utility</td>
</tr>
<tr>
<td>After adding the new GPU</td>
<td>
<strong>BIOS-related</strong> (Motherboard firmware bug)</td>
<td>Update BIOS to the latest version using ASUS EZ Flash 3</td>
</tr>
</tbody>
</table>
</div>
<p>A clean installation of the driver only provided a &#8220;temporary relief.&#8221; The root cause lay in the motherboard&#8217;s BIOS. If dump file analysis points to a driver issue, but reinstalling the driver doesn&#8217;t stop the problem from recurring, <strong>updating the BIOS</strong> is highly likely the only way to achieve a complete fix.</p>
<h2>
<p>  Timeline of the Issue<br />
</p></h2>
<h3>
<p>  4 Years Ago (Initial Windows 11 Installation)<br />
</p></h3>
<p>When I migrated to Windows 11 right after its release, my PC started failing to wake from sleep, automatically restarting a few minutes later instead.</p>
<p>I tweaked settings and reinstalled drivers, but nothing worked. Because my work kept getting interrupted by these random reboots, <strong>I quickly downgraded (rolled back) to Windows 10 to escape the nightmare.</strong></p>
<h3>
<p>  Around Fall 2025<br />
</p></h3>
<p>As the end of support for Windows 10 approached, I gathered my courage and upgraded to Windows 11 once again.</p>
<p>Remembering the nightmare from four years ago, I hesitantly put the PC to sleep. Surprisingly, instead of the post-restart screen, the screen woke up with all my active applications fully restored.<br />
It seemed that over the past 4 years (likely via Windows Updates), the system&#8217;s behavior had changed. Putting it to &#8220;sleep&#8221; actually triggered &#8220;Hibernation,&#8221; from which it could restore. While it wasn&#8217;t a pure sleep wake-up, I compromised and kept using it since my work state was preserved.</p>
<h3>
<p>  Right After Installing the GPU<br />
</p></h3>
<p>Wanting to run a local AI, I installed a new graphics card (ASUS DUAL-RX9060XT-16G).</p>
<p>The very next day, when I tried to wake the PC from sleep (hibernation) as usual, <strong>the exact same initial symptom from four years ago returned: &#8220;failed to wake from sleep -&gt; auto-restart.&#8221;</strong></p>
<h2>
<p>  Details of the Symptoms<br />
</p></h2>
<p>I had my keyboard configured to trigger the wake-up process. The behavior was as follows:</p>
<ol>
<li>Pressing a key on the keyboard did nothing; the monitor remained completely dark.</li>
<li>After a few minutes passed, the BIOS splash screen suddenly appeared.</li>
<li>The OS would then reboot entirely (losing all pre-sleep work states).</li>
</ol>
<p>There was no Blue Screen of Death (BSOD); I just found myself at the sign-in screen.</p>
<h2>
<p>  Phase 1: Identifying the Driver as the Cause &amp; Temporary Fix<br />
</p></h2>
<h3>
<p>  Step 1: Checking Status with Reliability Monitor and Event Viewer<br />
</p></h3>
<p>First, I used <strong>&#8220;View reliability history&#8221;</strong> (searchable from the taskbar) to pinpoint the exact date of the error. Then, I checked the <strong>Event Viewer</strong> for details.</p>
<p><strong>How to check Event Viewer:</strong></p>
<ol>
<li>Right-click the Start button -&gt; Select &#8220;Event Viewer&#8221;.</li>
<li>From the left tree, select &#8220;Windows Logs&#8221; -&gt; &#8220;System&#8221;.</li>
<li>Click &#8220;Filter Current Log&#8221; and check &#8220;Critical&#8221; and &#8220;Error&#8221; to narrow down the results.</li>
</ol>
<p><strong>Main errors identified:</strong></p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Event ID</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong>41</strong> (Kernel-Power)</td>
<td>Indicates the system rebooted without a clean shutdown first. It doesn&#8217;t pinpoint the cause but helps identify the exact time of the crash.</td>
</tr>
<tr>
<td>
<strong>1001</strong> (BugCheck)</td>
<td>Recorded when a BSOD occurs. The stop code can be confirmed here.</td>
</tr>
</tbody>
</table>
</div>
<p>In the <strong>Reliability Monitor</strong>, I also found the following error:</p>
<ul>
<li>
<strong>LiveKernelEvent 141</strong> (Video Hardware Error): Indicates that the GPU driver stopped responding for a certain period, and Windows attempted to forcibly reset it.</li>
</ul>
<h3>
<p>  Step 2: Analyzing the Dump File with WinDbg<br />
</p></h3>
<p>Since Event Viewer only told me that the &#8220;GPU driver crashed,&#8221; I proceeded to analyze the dump file (<code>.dmp</code>) to find the underlying cause.</p>
<p><strong>Dump file location:</strong> <code>C:WindowsMinidump</code></p>
<p><strong>Analysis steps:</strong></p>
<ol>
<li>Install Microsoft&#8217;s official <strong>&#8220;WinDbg&#8221;</strong> (available via Microsoft Store or Windows SDK).</li>
<li>Open the dump file (<code>.dmp</code>) in WinDbg.</li>
<li>Run the analysis command <code>!analyze -v</code> to get the debug log.</li>
<li>Paste the obtained log into a Generative AI for analysis.</li>
</ol>
<blockquote>
<p><strong>Note:</strong><br />
Simply passing the raw debug log to a Generative AI yields highly accurate analysis. Even if you aren&#8217;t familiar with WinDbg, you can get through this just by copy-pasting the logs.</p>
</blockquote>
<p><strong>What the analysis revealed:</strong>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>BugCheck: 0x000000a0 (INTERNAL_POWER_ERROR)
Parameter 1: 0xf1
</code></pre>
</div>
<p><code>0xa0</code> with Parameter <code>0xf1</code> means a <strong>failure to transition to Modern Standby (S0 Low Power Idle)</strong>. It turned out that during the transition to or from sleep, the AMD Radeon graphics driver <strong><code>amdkmdag.sys</code></strong> stopped responding (hung), leading the OS to interpret it as a &#8220;fatal power error&#8221; and forcibly restart the system.</p>
<h3>
<p>  Step 3: Clean Installation of the Driver<br />
</p></h3>
<p>Since the cause was narrowed down to the AMD driver, I performed a clean install using the official <strong>&#8220;AMD Cleanup Utility&#8221;</strong>.</p>
<blockquote>
<p><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Important Warning:</strong><br />
The AMD Cleanup Utility runs in Safe Mode, which may disconnect your internet. <strong>Make sure to download the latest driver installer BEFORE starting this process.</strong></p>
</blockquote>
<p>Driver used this time: <strong>AMD Software: Adrenalin Edition 26.3.1 (WHQL Recommended)</strong></p>
<p>Interestingly, I was already using the latest driver when the issue occurred. The problem wasn&#8217;t the version itself, but rather <strong>incomplete driver remnants left behind by normal uninstallations</strong>. Complete removal via the AMD Cleanup Utility and subsequent reinstallation was required.</p>
<p><strong>Clean Installation Steps:</strong></p>
<p><strong>1. Preparation (Download)</strong></p>
<ul>
<li>Download the latest &#8220;AMD Software: Adrenalin Edition&#8221; installer from the official AMD website.</li>
<li>Download the &#8220;AMD Cleanup Utility&#8221; (<code>amdcleanuputility.exe</code>) from the official AMD support page.</li>
</ul>
<p><strong>2. Removing Current Drivers</strong></p>
<ol>
<li>Run <code>amdcleanuputility.exe</code>.</li>
<li>A prompt will ask if you want to reboot into Safe Mode. Click <strong>&#8220;Yes&#8221;</strong>.</li>
<li>The PC will automatically restart and boot into Safe Mode.</li>
<li>Once in Safe Mode, the tool launches automatically. When it asks to remove all AMD drivers and components, click <strong>&#8220;OK&#8221;</strong>.</li>
<li>The screen may flicker during removal—this is normal.</li>
<li>When it says &#8220;AMD Cleanup Utility has successfully completed,&#8221; click <strong>&#8220;OK&#8221;</strong> -&gt; <strong>&#8220;Yes (Reboot)&#8221;</strong>.</li>
</ol>
<p><strong>3. Reinstalling the Driver</strong></p>
<ol>
<li>Once Windows boots normally, run the installer you downloaded earlier.</li>
<li>Follow the on-screen instructions to complete the installation.</li>
<li>Restart the PC one more time just to be safe.</li>
</ol>
<p>With this fix, the system stopped relying on the &#8220;fake sleep&#8221; (hibernation) workaround, and the sleep wake-up failure seemed temporarily resolved.</p>
<p>Alternative solutions suggested by GenAI (Not needed in this case)</p>
<p>Based on the dump analysis, the Generative AI also suggested the following workarounds, but they were irrelevant to my environment:</p>
<ul>
<li>Disabling the integrated graphics (iGPU)</li>
<li>Disabling PCIe Link State Power Management</li>
<li>Disabling Modern Standby (via registry/settings)</li>
</ul>
<p>These are often BIOS-level settings, which might not exist depending on your motherboard, or might have already been addressed by default.</p>
<h2>
<p>  Phase 2: Recurrence &amp; Identifying the Root Cause<br />
</p></h2>
<h3>
<p>  Recurrence After 1 Week<br />
</p></h3>
<p>About a week after the driver update, the automatic restart due to sleep wake-up failure <strong>happened again</strong>.</p>
<h3>
<p>  Narrowing Down Reproduction Conditions<br />
</p></h3>
<p>After repeated testing, I identified a specific trigger: <strong>The wake-up failure occurred when I put the PC to sleep while leaving an AI model loaded in &#8220;Lemonade&#8221; (a local server software for running LLMs).</strong></p>
<p>I strongly suspected that entering sleep mode while heavily occupying the GPU VRAM was the trigger.</p>
<h3>
<p>  Re-investigation<br />
</p></h3>
<p>I analyzed the dump files with WinDbg again and consulted the GenAI, but it gave the same response as before: &#8220;Driver issue (<code>amdkmdag.sys</code>).&#8221; No new clues were found there.</p>
<p>I then manually searched Reddit and international forums. There, I found multiple reports stating, <strong>&#8220;Updating the BIOS fixed the sleep wake-up bug.&#8221;</strong> This raised the possibility of a fundamental flaw in the motherboard&#8217;s firmware.</p>
<h2>
<p>  Phase 3: Root Cause Resolution via BIOS Update<br />
</p></h2>
<h3>
<p>  BIOS Update Procedure<br />
</p></h3>
<p>For ASUS motherboards, you can use <strong>&#8220;ASUS EZ Flash 3&#8221;</strong> to update the BIOS directly from the BIOS screen without relying on the OS, as long as you have the BIOS image file.</p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Item</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>Version Before Update</td>
<td>5031 (2025/04/01)</td>
</tr>
<tr>
<td>Version After Update</td>
<td>5044 Beta (2026/02/02)</td>
</tr>
</tbody>
</table>
</div>
<p><strong>Steps:</strong></p>
<ol>
<li>Download the latest BIOS for your motherboard (TUF GAMING X570-PLUS) from the ASUS official website.</li>
<li>Place the BIOS file in the root directory of a FAT-formatted USB flash drive.</li>
<li>Restart the PC and enter the BIOS screen (by pressing the <code>Delete</code> key).</li>
<li>Navigate to &#8220;Tool&#8221; -&gt; &#8220;ASUS EZ Flash 3 Utility&#8221;.</li>
<li>Select the USB flash drive, choose the BIOS file, and execute the update.</li>
<li>The PC will automatically restart upon completion.</li>
</ol>
<blockquote>
<p><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Warning:</strong><br />
A failed BIOS update carries the <strong>risk of rendering your PC unbootable</strong> (bricking). Please ensure the following before proceeding:</p>
<ul>
<li>Use a UPS or ensure a highly stable power connection to prevent power loss during the update.</li>
<li>Take note of your current BIOS settings just in case.</li>
</ul>
</blockquote>
<h3>
<p>  Results<br />
</p></h3>
<p>After the update, I tested putting the PC to sleep while leaving the AI model loaded. It woke up perfectly without any issues. <strong>The long-standing bug was finally and completely resolved.</strong></p>
<h2>
<p>  <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Side Effects of BIOS Updates &amp; Workarounds<br />
</p></h2>
<p>Updating the BIOS causes the following side effects. I highly recommend preparing for them in advance.</p>
<h3>
<p>  1. Windows Sign-in PIN Gets Reset<br />
</p></h3>
<p>After a BIOS update, the PIN used for Windows Hello is cleared.</p>
<p><strong>What to do beforehand:</strong></p>
<ul>
<li>Ensure you can sign in using your Microsoft account password.</li>
<li>Make sure you have access to your Microsoft account recovery email (a verification code may be sent when logging into the OS).</li>
</ul>
<blockquote>
<p><strong>Note:</strong><br />
In my case, I happened to have my Windows login password safely stored in a custom-built Android app I created for password and account management, so I was able to sign in without any trouble.</p>
</blockquote>
<p><a href="https://play.google.com/store/apps/details?id=com.kuroappworks.seclip" rel="noopener noreferrer"><img fetchpriority="high" decoding="async" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vol2h1qhkazk3zyrsde.png" alt=" " width="460" height="150" /></a></p>
<h3>
<p>  2. Passkeys Are Disabled<br />
</p></h3>
<p>Because the PIN is reset, any <strong>passkeys</strong> tied to your PC via Windows Hello (such as for your Google account) will become unusable. Even if you set your PIN back to exactly what it was, they won&#8217;t recover. You will need to <strong>re-register your passkeys</strong> for each respective service.</p>
<h2>
<p>  Conclusion<br />
</p></h2>
<p>While the WinDbg dump analysis consistently pointed only to a crash in <code>amdkmdag.sys</code>, the breakthrough that led me to suspect the BIOS came from information found on international forums.</p>
<p>The key takeaway from this experience is that <strong>sleep-related bugs are surprisingly often caused by the BIOS</strong>.<br />
I hope this log helps anyone dealing with the same frustrating issue!</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/solved-windows-11-failed-to-wake-from-sleep-and-restarts-fixing-a-4-year-old-bug-with-a-bios-update/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>JSON Schema: How to Validate API Responses Before They Break Your App</title>
		<link>https://codango.com/json-schema-how-to-validate-api-responses-before-they-break-your-app/</link>
					<comments>https://codango.com/json-schema-how-to-validate-api-responses-before-they-break-your-app/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 10:06:11 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/json-schema-how-to-validate-api-responses-before-they-break-your-app/</guid>

					<description><![CDATA[If you&#8217;ve ever shipped a bug because an API returned null where you expected a string, you&#8217;ve already experienced the problem JSON Schema solves. JSON Schema is a vocabulary that <a class="more-link" href="https://codango.com/json-schema-how-to-validate-api-responses-before-they-break-your-app/">Continue reading <span class="screen-reader-text">  JSON Schema: How to Validate API Responses Before They Break Your App</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;ve ever shipped a bug because an API returned <code>null</code> where you expected a string, you&#8217;ve already experienced the problem JSON Schema solves.</p>
<p>JSON Schema is a vocabulary that lets you describe the structure of your JSON data and validate it automatically. It&#8217;s been around since 2009 and is now a draft standard under the IETF. If you work with APIs, configs, or any structured JSON, it&#8217;s worth knowing.</p>
<h2>
<p>  What JSON Schema actually does<br />
</p></h2>
<p>A JSON Schema is itself a JSON document that describes what valid JSON looks like. Here&#8217;s a minimal example:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"$schema"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://json-schema.org/draft-07/schema#"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"required"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"id"</span><span class="p">,</span><span class="w"> </span><span class="s2">"email"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"integer"</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"email"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span><span class="w"> </span><span class="nl">"format"</span><span class="p">:</span><span class="w"> </span><span class="s2">"email"</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"age"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"integer"</span><span class="p">,</span><span class="w"> </span><span class="nl">"minimum"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="nl">"maximum"</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="w"> </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p>This schema says: the JSON must be an object with <code>id</code> (integer) and <code>email</code> (string, email format) as required fields. <code>age</code> is optional but, if present, must be a non-negative integer under 150.</p>
<p>Run any JSON against this schema and you get a pass/fail result with specific error messages.</p>
<h2>
<p>  The core keywords you need to know<br />
</p></h2>
<p><strong>Type keywords</strong>: <code>"type": "string"</code>, <code>"type": "integer"</code>, <code>"type": "number"</code>, <code>"type": "boolean"</code>, <code>"type": "array"</code>, <code>"type": "object"</code>, <code>"type": "null"</code>. You can allow multiple types with an array: <code>"type": ["string", "null"]</code>.</p>
<p><strong>String constraints</strong>: <code>minLength</code>, <code>maxLength</code>, <code>pattern</code> (regex). For example: <code>"pattern": "^[a-z]{2,3}$"</code> would match a 2–3 character lowercase language code.</p>
<p><strong>Number constraints</strong>: <code>minimum</code>, <code>maximum</code>, <code>exclusiveMinimum</code>, <code>exclusiveMaximum</code>, <code>multipleOf</code>.</p>
<p><strong>Array constraints</strong>: <code>items</code> (schema for each element), <code>minItems</code>, <code>maxItems</code>, <code>uniqueItems</code>. With <code>uniqueItems: true</code>, duplicate entries fail validation.</p>
<p><strong>Object constraints</strong>: <code>properties</code> (per-key schemas), <code>required</code> (list of required keys), <code>additionalProperties</code> (set to <code>false</code> to ban keys not listed in <code>properties</code>).</p>
<p><strong>Combining schemas</strong>: <code>allOf</code>, <code>anyOf</code>, <code>oneOf</code>, <code>not</code>. These let you compose complex validation rules from simpler ones.</p>
<h2>
<p>  A real-world example<br />
</p></h2>
<p>Say you&#8217;re calling a payment API that returns transaction objects. You want to catch bad responses before they reach your business logic:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"$schema"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://json-schema.org/draft-07/schema#"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"object"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"required"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"transaction_id"</span><span class="p">,</span><span class="w"> </span><span class="s2">"amount"</span><span class="p">,</span><span class="w"> </span><span class="s2">"currency"</span><span class="p">,</span><span class="w"> </span><span class="s2">"status"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"transaction_id"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span><span class="w"> </span><span class="nl">"minLength"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"amount"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"number"</span><span class="p">,</span><span class="w"> </span><span class="nl">"exclusiveMinimum"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"currency"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span><span class="w"> </span><span class="nl">"pattern"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^[A-Z]{3}$"</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"string"</span><span class="p">,</span><span class="w"> </span><span class="nl">"enum"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"pending"</span><span class="p">,</span><span class="w"> </span><span class="s2">"completed"</span><span class="p">,</span><span class="w"> </span><span class="s2">"failed"</span><span class="p">,</span><span class="w"> </span><span class="s2">"refunded"</span><span class="p">]</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"metadata"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"object"</span><span class="w"> </span><span class="p">}</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"additionalProperties"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p>This rejects: zero or negative amounts, currencies that aren&#8217;t 3-letter ISO codes, statuses outside the defined enum, and any unexpected extra fields.</p>
<h2>
<p>  Where JSON Schema is used<br />
</p></h2>
<ul>
<li>
<strong>API contract testing</strong> — validate responses from external APIs before processing</li>
<li>
<strong>Configuration files</strong> — VS Code uses JSON Schema to provide autocomplete and inline validation for <code>settings.json</code>, <code>launch.json</code>, and many extension configs</li>
<li>
<strong>Form validation</strong> — libraries like Ajv run schema validation client-side</li>
<li>
<strong>CI pipeline checks</strong> — validate generated artifacts before deploying</li>
<li>
<strong>OpenAPI specs</strong> — OpenAPI 3.x uses JSON Schema for request/response body definitions</li>
</ul>
<h2>
<p>  Draft versions and compatibility<br />
</p></h2>
<p>The most widely supported version is <strong>draft-07</strong>. Draft-04 is still common in older codebases. Newer drafts (2019-09, 2020-12) add features like <code>$defs</code>, <code>unevaluatedProperties</code>, and <code>prefixItems</code> for tuple validation, but library support is patchy.</p>
<p>If you&#8217;re starting fresh, use draft-07 — you get broad tool and library support with minimal compatibility headaches.</p>
<h2>
<p>  Validating quickly without writing code<br />
</p></h2>
<p>If you want to test a schema against some JSON right now without setting up a project, you can use a browser-based validator. I built one at <a href="https://snappytools.app/json-formatter/" rel="noopener noreferrer">SnappyTools JSON Formatter</a> for formatting and validating JSON structure — paste your JSON, see errors highlighted instantly, all client-side with no data sent anywhere.</p>
<p>For schema-specific validation (pairing a schema with an instance and seeing which keywords fail), tools like jsonschema.dev and jsonschemavalidator.net are useful references.</p>
<h2>
<p>  The quick takeaway<br />
</p></h2>
<p>JSON Schema is the most practical way to add a validation layer between your app and untrusted JSON data. You don&#8217;t need a library for simple cases — just knowing the keywords lets you write schemas by hand and reason about what JSON your code will accept.</p>
<p>Start with <code>type</code>, <code>required</code>, and <code>properties</code>. Add <code>minimum</code>/<code>maximum</code> for numbers, <code>pattern</code> for strings, and <code>enum</code> for fixed value sets. That covers 80% of real-world validation needs.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/json-schema-how-to-validate-api-responses-before-they-break-your-app/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>5 Common JSON Errors That Break APIs (and How to Fix Them)</title>
		<link>https://codango.com/5-common-json-errors-that-break-apis-and-how-to-fix-them/</link>
					<comments>https://codango.com/5-common-json-errors-that-break-apis-and-how-to-fix-them/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 10:00:41 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/5-common-json-errors-that-break-apis-and-how-to-fix-them/</guid>

					<description><![CDATA[5 Common JSON Errors That Break APIs (and How to Fix Them) If you’ve worked with APIs for even a short time, you’ve probably run into this: “Why is this <a class="more-link" href="https://codango.com/5-common-json-errors-that-break-apis-and-how-to-fix-them/">Continue reading <span class="screen-reader-text">  5 Common JSON Errors That Break APIs (and How to Fix Them)</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<h2>
<p>  5 Common JSON Errors That Break APIs (and How to Fix Them)<br />
</p></h2>
<p>If you’ve worked with APIs for even a short time, you’ve probably run into this:</p>
<blockquote>
<p>“Why is this JSON not working?!”</p>
</blockquote>
<p>Everything looks fine… until your parser throws an error and your app breaks.</p>
<p>The truth is, <strong>most JSON issues are small but deadly</strong> — a missing comma, a trailing bracket, or an incorrect structure can completely break your API flow.</p>
<p>In this post, I’ll walk through the <strong>5 most common JSON errors developers face</strong>, along with simple fixes and examples.</p>
<h2>
<p>  1. Missing Commas Between Fields<br />
</p></h2>
<p>This is probably the most common issue.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Invalid JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="w">
  </span><span class="nl">"age"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fixed JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"age"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p><strong>Why it happens:</strong><br />
When manually editing JSON, it’s easy to forget commas between key-value pairs.</p>
<h2>
<p>  2. Trailing Commas<br />
</p></h2>
<p>Some languages allow trailing commas — JSON does NOT.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Invalid JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"age"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="p">,</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fixed JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"age"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p><strong>Tip:</strong><br />
If you&#8217;re copying JSON from JavaScript objects, watch out for this.</p>
<h2>
<p>  3. Unquoted Keys or Strings<br />
</p></h2>
<p>JSON requires <strong>double quotes</strong> for keys and string values.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Invalid JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="p">{</span>
  <span class="nl">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">John</span><span class="dl">"</span><span class="p">,</span>
  <span class="nx">age</span><span class="p">:</span> <span class="mi">30</span>
<span class="p">}</span>
</code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fixed JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"age"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<h2>
<p>  4. Incorrect Data Types<br />
</p></h2>
<p>Sometimes values are accidentally wrapped as strings instead of numbers or booleans.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Problematic JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"isActive"</span><span class="p">:</span><span class="w"> </span><span class="s2">"true"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"count"</span><span class="p">:</span><span class="w"> </span><span class="s2">"10"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Better JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"isActive"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
  </span><span class="nl">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<p><strong>Why it matters:</strong><br />
Your backend or frontend logic may behave incorrectly if types are wrong.</p>
<h2>
<p>  5. Unclosed Brackets or Braces<br />
</p></h2>
<p>This is another classic.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Invalid JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"user"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="w">
</span></code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fixed JSON:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight json"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"user"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
</div>
<h2>
<p>  How to Fix JSON Faster<br />
</p></h2>
<p>Manually debugging JSON is frustrating — especially with large API responses.</p>
<p>A better approach is to use a tool that can:</p>
<ul>
<li>Validate JSON instantly</li>
<li>Highlight errors</li>
<li>Format and beautify the structure</li>
<li>Fix common issues automatically</li>
</ul>
<p>I’ve been using a simple tool called <strong>Fixzi</strong> for this:</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://fixzi.ai/json-validator" rel="noopener noreferrer">https://fixzi.ai/json-validator</a></p>
<p>It helps quickly:</p>
<ul>
<li>Validate JSON</li>
<li>Fix invalid structures</li>
<li>Format and clean large payloads</li>
<li>Compare JSON responses (useful for APIs)</li>
</ul>
<h2>
<p>  Final Thoughts<br />
</p></h2>
<p>JSON errors are small, but they can cause <strong>big production issues</strong> — especially when working with APIs, webhooks, or third-party integrations.</p>
<p>If you’re debugging JSON frequently:</p>
<ul>
<li>Always validate before using it</li>
<li>Use proper formatting tools</li>
<li>Avoid manual edits when possible</li>
</ul>
<p>If you’ve faced other tricky JSON issues, I’d love to hear them <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f447.png" alt="👇" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/5-common-json-errors-that-break-apis-and-how-to-fix-them/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>You Can Probably Use Claude Code for Free at Work</title>
		<link>https://codango.com/you-can-probably-use-claude-code-for-free-at-work/</link>
					<comments>https://codango.com/you-can-probably-use-claude-code-for-free-at-work/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 02:03:18 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/you-can-probably-use-claude-code-for-free-at-work/</guid>

					<description><![CDATA[If your company has already deployed Claude models on Microsoft Foundry, you can basically use Claude Code for free and save $17/month on a Claude subscription. Check Your Access to <a class="more-link" href="https://codango.com/you-can-probably-use-claude-code-for-free-at-work/">Continue reading <span class="screen-reader-text">  You Can Probably Use Claude Code for Free at Work</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>If your company has already deployed Claude models on Microsoft Foundry, you can basically use Claude Code for free and save <strong>$17/month</strong> on a Claude subscription.</p>
<h2>
<p>  Check Your Access to Foundry<br />
</p></h2>
<p><a href="https://azure.microsoft.com/en-us/products/ai-foundry" rel="noopener noreferrer">Microsoft Foundry</a> (formerly Azure AI Studio) is a unified, enterprise-grade AI platform-as-a-service designed for developers to build, customize, and deploy AI applications and agents.</p>
<ol>
<li>Go to <a href="https://ai.azure.com/nextgen" rel="noopener noreferrer">https://ai.azure.com/nextgen</a>
</li>
<li>Click <strong>Build</strong> on the top navigation bar</li>
<li>Click <strong>Models</strong> in the side menu</li>
</ol>
<p>Make sure your organization already has Claude models deployed in Foundry (for example <code>claude-opus-4-7</code>).</p>
<h2>
<p>  Connect Foundry Models to Claude Code<br />
</p></h2>
<p>I recommend using Entra ID + Azure CLI authentication. It&#8217;s safer and more convenient than managing API keys manually.</p>
<p>Install Azure CLI before continuing:</p>
<ul>
<li><a href="https://learn.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" rel="noopener noreferrer">https://learn.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest</a></li>
</ul>
<p>After installing Azure CLI, sign in with:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>az login
</code></pre>
</div>
<p>Set the following environment variables to enable Microsoft Foundry integration in Claude Code.</p>
<p>I usually put them in my .zshrc.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code><span class="c"># Enable Microsoft Foundry integration</span>
<span class="nb">export </span><span class="nv">CLAUDE_CODE_USE_FOUNDRY</span><span class="o">=</span>1

<span class="c"># Azure resource name (replace {resource} with your resource name)</span>
<span class="nb">export </span><span class="nv">ANTHROPIC_FOUNDRY_RESOURCE</span><span class="o">={</span>resource<span class="o">}</span>

<span class="c"># Or provide the full base URL:</span>
<span class="c"># export ANTHROPIC_FOUNDRY_BASE_URL=https://{resource}.services.ai.azure.com/anthropic</span>
</code></pre>
</div>
<blockquote>
<p>In the current Foundry UI, <strong>resource</strong> are renamed to <strong>project</strong>.</p>
</blockquote>
<p>Set the model variables to match your deployment names.</p>
<p>By default, the opus alias on Foundry may still resolve to Opus 4.6. To make sure Claude Code uses Opus 4.7, explicitly set:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code><span class="nb">export </span><span class="nv">ANTHROPIC_DEFAULT_OPUS_MODEL</span><span class="o">=</span><span class="s1">'claude-opus-4-7'</span>
<span class="nb">export </span><span class="nv">ANTHROPIC_DEFAULT_SONNET_MODEL</span><span class="o">=</span><span class="s1">'claude-sonnet-4-6'</span>
<span class="nb">export </span><span class="nv">ANTHROPIC_DEFAULT_HAIKU_MODEL</span><span class="o">=</span><span class="s1">'claude-haiku-4-5'</span>
</code></pre>
</div>
<h2>
<p>  Common Issues<br />
</p></h2>
<h4>
<p>  Wrong Azure tenant<br />
</p></h4>
<p>If your company uses multiple Azure tenants, <code>az login</code> may authenticate against the wrong one.</p>
<p>Check your current tenant with:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>az account show
</code></pre>
</div>
<p>Switch tenants if needed:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>az login <span class="nt">--tenant</span> &lt;tenant-id&gt;
</code></pre>
</div>
<h4>
<p>  Deployment name mismatch<br />
</p></h4>
<p>The model name in Claude Code must match the deployment name configured in Foundry.</p>
<p>For example:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code><span class="nb">export </span><span class="nv">ANTHROPIC_DEFAULT_OPUS_MODEL</span><span class="o">=</span><span class="s1">'claude-opus-4-7'</span>
</code></pre>
</div>
<p>must exactly match the deployment name shown in the Foundry Models page.</p>
<h1>
<p>  Side Notes<br />
</p></h1>
<p>Some companies provide Azure subscriptions or enterprise credits for internal development.</p>
<p>So even if your IT team has not deployed Claude models yet, you may still be able to deploy them yourself.</p>
<p>Just make sure you have permission before creating resources.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/you-can-probably-use-claude-code-for-free-at-work/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Regulalar Expression</title>
		<link>https://codango.com/regulalar-expression/</link>
					<comments>https://codango.com/regulalar-expression/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 01:47:34 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/regulalar-expression/</guid>

					<description><![CDATA[Mastering Regular Expressions in JavaScript: From Basics to Real-World Validation At first glance, a regex pattern looks like a cat walked across your keyboard,a chaotic string of slashes, brackets, and <a class="more-link" href="https://codango.com/regulalar-expression/">Continue reading <span class="screen-reader-text">  Regulalar Expression</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<h2>
<p>  Mastering Regular Expressions in JavaScript: From Basics to Real-World Validation<br />
</p></h2>
<p>At first glance, a regex pattern looks like a cat walked across your keyboard,a chaotic string of slashes, brackets, and symbols. However, once you decode the syntax, it becomes one of the most powerful tools in your developer toolkit.<br />
Below is the break down of how regex works in JavaScript and build a robust pattern to validate something we use every day: <strong>email addresses</strong>.</p>
<h3>
<p>  What is a Regular Expression anyways?<br />
</p></h3>
<p>A <strong>Regular Expression</strong> is an object that describes a pattern of characters. In JavaScript, you can create them in two ways:</p>
<ol>
<li>
<strong>Literal Notation:</strong> /pattern/flags</li>
<li>
<strong>Constructor:</strong> new RegExp(&#8216;pattern&#8217;, &#8216;flags&#8217;)<br />
### The Core Building Blocks<br />
Before we tackle the email login, we need to understand the &#8220;alphabet&#8221; of regex:</li>
<li>
<strong>Character Classes:</strong>
<ul>
<li>d: Matches any digit (0-9).</li>
<li>w: Matches any alphanumeric character (letters, numbers, and underscores).</li>
<li>s: Matches whitespace (spaces, tabs).</li>
<li>.: The wildcard—matches any character except a newline.</li>
</ul>
</li>
<li>
<strong>Quantifiers:</strong>
<ul>
<li>+: Matches 1 or more of the preceding element.</li>
<li>*: Matches 0 or more.</li>
<li>{n,m}: Matches between n and m times.</li>
</ul>
</li>
<li>
<strong>Anchors:</strong>
<ul>
<li>^: Forces the match to start at the beginning of the string.</li>
<li>$: Forces the match to end at the end of the string.<br />
### Deep Dive: Validating an Email Address<br />
When we log in to a platform, the first line of defense is ensuring the input actually looks like an email. Let’s build a regex for a standard email like <a href="mailto:zone01.recode@company.co.ke">zone01.recode@company.co.ke</a>.<br />
#### 1. The Local Part (zone01 .recode)<br />
We want to allow letters, numbers, dots, and underscores.</li>
</ul>
</li>
<li>
<strong>Pattern:</strong> ^[a-zA-Z0-9._%+-]+</li>
<li>
<strong>Explanation:</strong> We start at the beginning (^) and allow a set of characters inside the square brackets. The + ensures there is at least one character.<br />
#### 2. The &#8220;@&#8221; Symbol<br />
We just need the literal character.</li>
<li>
<strong>Pattern:</strong> @<br />
#### 3. The Domain (company)<br />
Similar to the local part, but usually without the special symbols.</li>
<li>
<strong>Pattern:</strong> [a-zA-Z0-9.-]+<br />
#### 4. The TLD (.co.ke or .com)<br />
We need a literal dot, followed by letters. Since a dot . is a wildcard in regex, we must <strong>escape</strong> it with a backslash ..</li>
<li>
<strong>Pattern:</strong> .[a-zA-Z]{2,}$</li>
<li>
<strong>Explanation:</strong> This looks for a dot and at least two letters at the very end of the string ($).<br />
#### Putting it all together:
</li>
</ol>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">emailRegex</span> <span class="o">=</span> <span class="sr">/^</span><span class="se">[</span><span class="sr">a-zA-Z0-9._%+-</span><span class="se">]</span><span class="sr">+@</span><span class="se">[</span><span class="sr">a-zA-Z0-9.-</span><span class="se">]</span><span class="sr">+</span><span class="se">.[</span><span class="sr">a-zA-Z</span><span class="se">]{2,}</span><span class="sr">$/</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">testEmail</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">dev_user123@zone01.edu</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">emailRegex</span><span class="p">.</span><span class="nf">test</span><span class="p">(</span><span class="nx">testEmail</span><span class="p">));</span> <span class="c1">// Output: true</span>

</code></pre>
</div>
<h3>
<p>  Common Use Cases in Web Apps<br />
</p></h3>
<p>Beyond login forms, regex is used everywhere in full-stack development:</p>
<ul>
<li>
<strong>Password Strength:</strong> Checking for at least one capital letter, one number, and one special character.</li>
<li>
<strong>URL Parsing:</strong> Extracting slugs or IDs from a browser&#8217;s address bar.</li>
<li>
<strong>Data Scrubbing:</strong> Removing formatting from phone numbers (e.g., changing +254 712-345-678 to 254712345678).</li>
<li>
<strong>Search and Replace:</strong> Swapping specific words across a whole document using the global /g flag.<br />
### Helpful Methods in JavaScript<br />
To use your patterns, you’ll mostly use these two methods:</li>
<li>
<strong>regex.test(string)</strong>: Returns true or false. Perfect for form validation.</li>
<li>
<strong>string.match(regex)</strong>: Returns an array of matches. Great for extracting information from a large block of text.<br />
&gt; <strong>Pro Tip:</strong> Use tools like <strong>RegEx101</strong> to test your patterns in real-time before putting them into your code. It provides a &#8220;flavor&#8221; setting—make sure to select <strong>ECMAScript (JavaScript)</strong>.<br />
&gt;<br />
### Conclusion<br />
Regex might feel like a steep climb, but it is a &#8220;learn once, use everywhere&#8221; skill. Whether you are working on a Go backend or a JavaScript frontend, the logic remains largely the same. Keep practicing by trying to validate other common inputs like phone numbers or postal codes!</li>
</ul>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/regulalar-expression/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[EN] Delegated Resource Identifier (DRI): a pattern for persistent references in microservices</title>
		<link>https://codango.com/en-delegated-resource-identifier-dri-a-pattern-for-persistent-references-in-microservices/</link>
					<comments>https://codango.com/en-delegated-resource-identifier-dri-a-pattern-for-persistent-references-in-microservices/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 01:39:17 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/en-delegated-resource-identifier-dri-a-pattern-for-persistent-references-in-microservices/</guid>

					<description><![CDATA[Also available in Spanish If you&#8217;ve ever stored a URL in a database and later regretted it, this is for you. It&#8217;s a familiar scenario: a service needs to keep <a class="more-link" href="https://codango.com/en-delegated-resource-identifier-dri-a-pattern-for-persistent-references-in-microservices/">Continue reading <span class="screen-reader-text">  [EN] Delegated Resource Identifier (DRI): a pattern for persistent references in microservices</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p><a href="https://dev.to/edgardo_genini/es-delegated-resource-identifier-dri-un-patron-para-referencias-persistentes-en-microservicios-big">Also available in Spanish</a></p>
<p>If you&#8217;ve ever stored a URL in a database and later regretted it, this is for you.</p>
<p>It&#8217;s a familiar scenario: a service needs to keep a reference to a resource that lives in another service. The obvious solution is to store the URL. It works — until the host changes, the API gets a new version, or the team decides to restructure the paths. Suddenly all the stored references are broken, and tracking down the impact becomes a bigger problem than it should be.</p>
<p>The root issue is that a URL mixes two different things: <em>what</em> the resource is and <em>where</em> it lives. When you store a URL, you&#8217;re betting that location won&#8217;t change. In systems that evolve, that&#8217;s usually a losing bet.</p>
<h2>
<p>  The idea<br />
</p></h2>
<p>What if instead of storing where the resource lives, you store your own identifier that a gateway knows how to resolve?
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>commerce:orders/order:id=ARG-2024-00091872
finance:accounts/customer:status:id=109234
health:coverage/credential:patient-id=12345678
</code></pre>
</div>
<p>Whoever stores the reference doesn&#8217;t need to know where the resource lives or how to access it. That&#8217;s the gateway&#8217;s responsibility. If the API changes, if the service migrates, if a new system appears: only the resolver changes. The stored references remain valid.</p>
<p>I called this scheme <strong>Delegated Resource Identifier (DRI)</strong>.</p>
<h2>
<p>  What this pattern is not<br />
</p></h2>
<ul>
<li>It&#8217;s not a standard</li>
<li>It requires a gateway as intermediary: it doesn&#8217;t apply when the client needs to access the resource directly without going through any intermediary</li>
<li>It doesn&#8217;t impose a context taxonomy: each team defines their own</li>
</ul>
<p>It&#8217;s a useful convention when you need persistent references to resources in a controlled ecosystem and want to centralize the resolution logic.</p>
<h2>
<p>  How it&#8217;s built<br />
</p></h2>
<p>The identifier has two parts separated by <code>/</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>&lt;context&gt;/&lt;resource&gt;
</code></pre>
</div>
<ul>
<li>
<strong>Context</strong> (left side): identifies the domain that knows how to resolve this type of resource. The gateway uses it for routing.</li>
<li>
<strong>Resource</strong> (right side): identifies the concrete resource. Its structure is defined by whoever implements the resolver.
</li>
</ul>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>commerce:orders/order:id=ARG-2024-00091872
└─── routing ───┘└─── concrete resource ──┘
</code></pre>
</div>
<p><code>:</code> separates hierarchical levels. <code>=</code> assigns values. Each side defines its own internal convention.</p>
<p>The identifier is built by whoever stores the reference, from the data they already have and the context they know. No external call required. A billing service that receives an order ID knows it belongs to <code>commerce:orders</code> and builds the DRI when persisting the reference.</p>
<p>The context can be omitted if the gateway has a default resolver:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>/order:id=ARG-2024-00091872
</code></pre>
</div>
<h2>
<p>  Some use cases<br />
</p></h2>
<h3>
<p>  E-commerce: retrieving an order<br />
</p></h3>
<p>A customer service system stores references to orders that can come from different channels: own store, marketplace, mobile app. Each channel has its own API.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>commerce:orders/order:id=ARG-2024-00091872
commerce:orders/order:id=MKT-2024-00034521
</code></pre>
</div>
<p>The <code>commerce:orders</code> resolver determines which channel each order belongs to based on the ID prefix and routes to the corresponding API. The identifier remains stable even if the channel&#8217;s API changes.</p>
<h3>
<p>  Fintech: customer account status<br />
</p></h3>
<p>A bank with legacy and modern systems running side by side. The resolver determines which system the customer lives in based on the ID value: customers with <code>id &lt; 50000</code> are in the legacy system, the rest in the modern one.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>finance:accounts/customer:status:id=109234
finance:accounts/customer:status:id=002871
</code></pre>
</div>
<p>The resolver also encapsulates the decision of which API version to use. And here something interesting emerges: the DRI has two moments in its lifecycle. When persisted, it&#8217;s just the identifier. When used for a query, it can be enriched with additional context using the same syntax:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>finance:accounts/customer:status:id=109234:date=20260101
</code></pre>
</div>
<p>The resolver can use that date to determine which API version applies. The persisted DRI doesn&#8217;t change; the additional context is added at query time.</p>
<h3>
<p>  Health: member coverage credential<br />
</p></h3>
<p>A member&#8217;s coverage can change over time: provider migration, gaps in coverage, or coverage with more than one provider. Storing the provider as a fixed value would produce outdated references.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>health:coverage/credential:patient-id=12345678
</code></pre>
</div>
<p>The resolver applies a fallback strategy: it queries the first available provider and if the credential isn&#8217;t found, tries the next one. The DRI resolves at query time, always reflecting the current state.</p>
<h3>
<p>  Multinational with tenant: supplier by legal entity<br />
</p></h3>
<p>A SaaS platform used by a company operating in multiple countries. Each country has its own supplier management system, its own API, and its own tax identifier format.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>tenant:acme:ar/supplier:cuit=20123456789
tenant:acme:cl/supplier:rut=76354921-5
tenant:acme:mx/supplier:rfc=XYZ123456789
</code></pre>
</div>
<p>The left side combines tenant and legal entity by country. The right side respects the local convention without the gateway knowing anything about it. Adding a new subsidiary or tenant means registering an additional resolver, without touching existing references. The context hierarchy grows naturally with the system.</p>
<h2>
<p>  How the gateway works<br />
</p></h2>
<p>The resolution flow is simple: the gateway receives the identifier, extracts the context, and delegates to the corresponding resolver.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>client  →  gateway  →  resolver(commerce:orders)  →  actual service
</code></pre>
</div>
<ol>
<li>Receives the identifier</li>
<li>Extracts the context (left side)</li>
<li>Delegates to the registered resolver for that context</li>
<li>The resolver fetches the resource and returns the response</li>
</ol>
<p>The gateway has no knowledge of concrete resources. As an orientative reference, a possible Java implementation:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight java"><code><span class="n">gateway</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"commerce:orders"</span><span class="o">,</span>   <span class="k">new</span> <span class="nc">OrderResolver</span><span class="o">());</span>
<span class="n">gateway</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"finance:accounts"</span><span class="o">,</span>  <span class="k">new</span> <span class="nc">AccountResolver</span><span class="o">());</span>
<span class="n">gateway</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"health:coverage"</span><span class="o">,</span>   <span class="k">new</span> <span class="nc">CoverageResolver</span><span class="o">());</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight java"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">ResourceResolver</span> <span class="o">{</span>
    <span class="nc">Response</span> <span class="nf">resolve</span><span class="o">(</span><span class="nc">ResourceIdentifier</span> <span class="n">identifier</span><span class="o">);</span>
<span class="o">}</span>
</code></pre>
</div>
<h2>
<p>  Optional preferences<br />
</p></h2>
<p>The identifier supports expressing preferences about how the resource should be resolved, with a syntax inspired by HTTP&#8217;s <code>Accept</code> header. For example, when querying available payment methods, you can indicate a preference for debit over credit:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>payments:methods/available:customer:id=109234;debit,q=0.9;credit,q=0.7
</code></pre>
</div>
<p>The meaning of <code>q</code> is defined by the contract between whoever builds the reference and whoever resolves it. The gateway doesn&#8217;t need to interpret it. This capability is completely optional.</p>
<p>I implemented this in Java and found it useful in practice. If you try it in your own context or have ideas to improve it, I&#8217;d love to read them in the comments.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/en-delegated-resource-identifier-dri-a-pattern-for-persistent-references-in-microservices/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[ES] Delegated Resource Identifier (DRI): un patrón para referencias persistentes en microservicios</title>
		<link>https://codango.com/es-delegated-resource-identifier-dri-un-patron-para-referencias-persistentes-en-microservicios/</link>
					<comments>https://codango.com/es-delegated-resource-identifier-dri-un-patron-para-referencias-persistentes-en-microservicios/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 01:36:45 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/es-delegated-resource-identifier-dri-un-patron-para-referencias-persistentes-en-microservicios/</guid>

					<description><![CDATA[También disponible en Inglés Si alguna vez guardaste una URL en una base de datos y después te arrepentiste, esto es para vos. Es un escenario conocido: un servicio necesita <a class="more-link" href="https://codango.com/es-delegated-resource-identifier-dri-un-patron-para-referencias-persistentes-en-microservicios/">Continue reading <span class="screen-reader-text">  [ES] Delegated Resource Identifier (DRI): un patrón para referencias persistentes en microservicios</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p><a href="https://dev.to/edgardo_genini/en-delegated-resource-identifier-dri-a-pattern-for-persistent-references-in-microservices-2o52">También disponible en Inglés</a></p>
<p>Si alguna vez guardaste una URL en una base de datos y después te arrepentiste, esto es para vos.</p>
<p>Es un escenario conocido: un servicio necesita mantener una referencia a un recurso que vive en otro servicio. La solución más obvia es guardar la URL. Funciona, hasta que el host cambia, la API sube de versión, o el equipo decide reestructurar los paths. De repente todas las referencias guardadas están rotas, y rastrear el impacto se convierte en un problema mayor de lo que debería ser.</p>
<p>El problema de fondo es que una URL mezcla dos cosas distintas: <em>qué es</em> el recurso y <em>dónde está</em>. Cuando guardás una URL estás apostando a que esa ubicación no va a cambiar. En sistemas que evolucionan, esa apuesta suele perderse.</p>
<h2>
<p>  La idea<br />
</p></h2>
<p>¿Qué pasaría si en lugar de guardar dónde está el recurso, guardás un identificador propio que un gateway sabe cómo resolver?
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>comercio:pedidos/orden:id=ARG-2024-00091872
finanzas:cuentas/cliente:estado:id=109234
salud:cobertura/credencial:patient-id=12345678
</code></pre>
</div>
<p>Quien guarda la referencia no necesita saber dónde vive el recurso ni cómo se accede. Esa responsabilidad la tiene el gateway. Si la API cambia, si el servicio migra, si aparece un sistema nuevo: solo cambia el resolver. Las referencias guardadas siguen siendo válidas.</p>
<p>A este esquema lo llamé <strong>Delegated Resource Identifier (DRI)</strong>.</p>
<h2>
<p>  Lo que este patrón no es<br />
</p></h2>
<ul>
<li>No es un estándar</li>
<li>Requiere un gateway como intermediario: no aplica cuando el cliente necesita acceder directamente al recurso sin pasar por ningún intermediario</li>
<li>No impone una taxonomía de contextos: cada equipo define la suya</li>
</ul>
<p>Es una convención útil cuando necesitás referencias persistentes a recursos en un ecosistema controlado, y querés centralizar la lógica de resolución.</p>
<h2>
<p>  Cómo se construye<br />
</p></h2>
<p>El identificador tiene dos partes separadas por <code>/</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>&lt;contexto&gt;/&lt;recurso&gt;
</code></pre>
</div>
<ul>
<li>
<strong>Contexto</strong> (lado izquierdo): identifica el dominio que sabe resolver este tipo de recurso. El gateway lo usa para rutear.</li>
<li>
<strong>Recurso</strong> (lado derecho): identifica el recurso concreto. Su estructura la define quien implementa el resolver.
</li>
</ul>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>comercio:pedidos/orden:id=ARG-2024-00091872
└─── ruteo ──────┘└─── recurso concreto ──┘
</code></pre>
</div>
<p>Los <code>:</code> separan niveles jerárquicos. El <code>=</code> asigna valores. Cada lado define su propia convención interna.</p>
<p>El identificador lo construye quien guarda la referencia, a partir del dato que ya tiene y el contexto que conoce. No requiere ninguna llamada externa. Un servicio de facturación que recibe el ID de una orden sabe que pertenece a <code>comercio:pedidos</code> y construye el DRI al momento de persistir la referencia.</p>
<p>El contexto puede omitirse si el gateway tiene un resolver por defecto:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>/orden:id=ARG-2024-00091872
</code></pre>
</div>
<h2>
<p>  Algunos casos de uso<br />
</p></h2>
<h3>
<p>  E-commerce: recuperar una orden<br />
</p></h3>
<p>Un servicio de atención al cliente guarda referencias a órdenes que pueden venir de distintos canales: tienda propia, marketplace, app móvil. Cada canal tiene su propia API.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>comercio:pedidos/orden:id=ARG-2024-00091872
comercio:pedidos/orden:id=MKT-2024-00034521
</code></pre>
</div>
<p>El resolver de <code>comercio:pedidos</code> determina a qué canal pertenece cada orden a partir del prefijo del ID y rutea hacia la API correspondiente. El identificador es estable aunque la API del canal cambie.</p>
<h3>
<p>  Fintech: estado de cuenta de un cliente<br />
</p></h3>
<p>Un banco con sistemas legacy y modernos conviviendo. El resolver determina en qué sistema vive el cliente según el valor del ID: clientes con <code>id &lt; 50000</code> en el sistema legacy, el resto en el moderno.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>finanzas:cuentas/cliente:estado:id=109234
finanzas:cuentas/cliente:estado:id=002871
</code></pre>
</div>
<p>El resolver encapsula también la decisión de qué versión de la API usar. Y acá aparece algo interesante: el DRI tiene dos momentos de vida. Cuando se persiste es solo el identificador. Cuando se usa para consultar, puede enriquecerse con contexto adicional usando la misma sintaxis:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>finanzas:cuentas/cliente:estado:id=109234:fecha=20260101
</code></pre>
</div>
<p>El resolver puede usar esa fecha para determinar qué versión de la API corresponde. El DRI persistido no cambia; el contexto adicional se agrega en el momento de la consulta.</p>
<h3>
<p>  Salud: credencial de cobertura de un afiliado<br />
</p></h3>
<p>La cobertura de un afiliado puede cambiar en el tiempo: migración de proveedor, períodos sin cobertura, cobertura en más de uno. Guardar el proveedor como dato fijo generaría referencias desactualizadas.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>salud:cobertura/credencial:patient-id=12345678
</code></pre>
</div>
<p>El resolver aplica una estrategia de fallback: consulta al primer proveedor disponible y si no encuentra la credencial prueba con el siguiente. El DRI resuelve en el momento de la consulta, reflejando siempre el estado actual.</p>
<h3>
<p>  Multinacional con tenant: proveedor por entidad legal<br />
</p></h3>
<p>Una plataforma SaaS con operaciones en múltiples países. Cada país tiene su propio sistema, su propia API y su propio formato de identificador fiscal.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>tenant:acme:ar/proveedor:cuit=20123456789
tenant:acme:cl/proveedor:rut=76354921-5
tenant:acme:mx/proveedor:rfc=XYZ123456789
</code></pre>
</div>
<p>El lado izquierdo combina tenant y entidad legal por país. El lado derecho respeta la convención local. Agregar una nueva filial o un nuevo tenant es registrar un resolver adicional, sin tocar las referencias existentes. La jerarquía del contexto crece naturalmente con el sistema.</p>
<h2>
<p>  Cómo funciona el gateway<br />
</p></h2>
<p>El flujo de resolución es simple: el gateway recibe el identificador, extrae el contexto y delega al resolver correspondiente.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>cliente  →  gateway  →  resolver(comercio:pedidos)  →  servicio real
</code></pre>
</div>
<ol>
<li>Recibe el identificador</li>
<li>Extrae el contexto (lado izquierdo)</li>
<li>Delega al resolver registrado para ese contexto</li>
<li>El resolver obtiene el recurso y devuelve la respuesta</li>
</ol>
<p>El gateway no conoce recursos concretos. A modo de referencia orientativa, una posible implementación en Java:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight java"><code><span class="n">gateway</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"comercio:pedidos"</span><span class="o">,</span> <span class="k">new</span> <span class="nc">OrderResolver</span><span class="o">());</span>
<span class="n">gateway</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"finanzas:cuentas"</span><span class="o">,</span> <span class="k">new</span> <span class="nc">AccountResolver</span><span class="o">());</span>
<span class="n">gateway</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"salud:cobertura"</span><span class="o">,</span>  <span class="k">new</span> <span class="nc">CoverageResolver</span><span class="o">());</span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight java"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">ResourceResolver</span> <span class="o">{</span>
    <span class="nc">Response</span> <span class="nf">resolve</span><span class="o">(</span><span class="nc">ResourceIdentifier</span> <span class="n">identifier</span><span class="o">);</span>
<span class="o">}</span>
</code></pre>
</div>
<h2>
<p>  Preferencias opcionales<br />
</p></h2>
<p>El identificador admite expresar preferencias sobre cómo debe resolverse el recurso, con una sintaxis inspirada en el header <code>Accept</code> de HTTP. Por ejemplo, al consultar medios de pago se puede indicar preferencia por débito sobre crédito:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>pagos:medios/disponibles:cliente:id=109234;debito,q=0.9;credito,q=0.7
</code></pre>
</div>
<p>El significado de <code>q</code> lo define el contrato entre quien construye la referencia y quien la resuelve. El gateway no necesita interpretarlo. Esta capacidad es completamente opcional.</p>
<p>Lo implementé en Java y me resultó útil en la práctica. Si lo probás en tu contexto o tenés ideas para mejorarlo, me interesa leerlo en los comentarios.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/es-delegated-resource-identifier-dri-un-patron-para-referencias-persistentes-en-microservicios/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>What if reactive effects are just pausable async tasks?</title>
		<link>https://codango.com/what-if-reactive-effects-are-just-pausable-async-tasks/</link>
					<comments>https://codango.com/what-if-reactive-effects-are-just-pausable-async-tasks/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Wed, 13 May 2026 01:24:44 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/what-if-reactive-effects-are-just-pausable-async-tasks/</guid>

					<description><![CDATA[I&#8217;ve been thinking about reactive programming from the runtime layer up. The question: what&#8217;s the minimum machinery you actually need to add on top of Rust&#8217;s async/await to get a <a class="more-link" href="https://codango.com/what-if-reactive-effects-are-just-pausable-async-tasks/">Continue reading <span class="screen-reader-text">  What if reactive effects are just pausable async tasks?</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been thinking about reactive programming from the runtime layer up. The question: what&#8217;s the minimum machinery you actually need to add on top of Rust&#8217;s async/await to get a working reactive system?</p>
<p>Three things Rust already gives you for free</p>
<ol>
<li>Pin&gt; = a suspended computation</li>
</ol>
<p>Think about it: a reactive effect is &#8220;a piece of code paused, waiting for its dependencies to change, then re-executing.&#8221; That&#8217;s exactly what a future stuck at Poll::Pending is.</p>
<p>scope.spawn(async move {<br />
    loop {<br />
        count.changed().await;  // suspends here<br />
        println!(&#8220;count = {}&#8221;, count.read());<br />
    }<br />
});</p>
<p>The SignalChangedFuture::poll() checks a monotonic version number. If unchanged, it subscribes a callback and returns Poll::Pending. The async executor polls other tasks. When the signal changes, the version bumps, the callback fires, the waker wakes, the executor re-polls. That&#8217;s the entire effect lifecycle — no custom scheduler, no effect graph traversal, no create_effect() abstraction.</p>
<p>The executor&#8217;s poll loop IS the effect scheduler. You don&#8217;t need a separate one.</p>
<ol>
<li>Waker = the notification dispatcher</li>
</ol>
<p>A reactive library has to decide &#8220;which effects need to re-run when signal X changes.&#8221; In the async model, this maps directly to &#8220;which futures should be re-polled.&#8221; The waker IS that dispatch mechanism:</p>
<p>fn poll(self: Pin&lt;&amp;mut Self&gt;, cx: &amp;mut Context&lt;&#8216;_&gt;) -&gt; Poll<a>Self::Output</a> {<br />
    if version_changed {<br />
        return Poll::Ready(self.signal.read());<br />
    }<br />
    // subscribe a callback that calls cx.waker().wake_by_ref()<br />
    // executor re-polls this future on next flush<br />
    Poll::Pending<br />
}</p>
<p>No separate notification queue. No topological sort of dependents. Just &#8220;wake the waker, executor picks it up.&#8221;</p>
<ol>
<li>Drop = cleanup</li>
</ol>
<p>Drop the scope that owns the tasks → all futures drop → each future&#8217;s Drop impl proactively unsubscribes from its signals → zero dangling subscribers. No manual on_cleanup() tokens, no effect disposal bookkeeping. Rust&#8217;s ownership does the work.</p>
<p>For deeply nested scopes (think UI component trees with hundreds of levels), cancellation uses BFS to collect all descendants, then iterates leaf-to-root — no recursive drop, no stack overflow.</p>
<p>The 20% Rust doesn&#8217;t give you: re-entrancy prevention</p>
<p>Here&#8217;s where pure async breaks down. If Signal::set() calls subscriber callbacks synchronously:</p>
<p>set() → callback → set() on same signal → callback → infinite loop<br />
set() → callback → subscribe new callback → mutate subscriber list during iteration → RefCell panic<br />
set() → callback → drop owning scope → borrow conflict</p>
<p>The async model alone can&#8217;t prevent this. You need a deferred notification state machine.</p>
<p>The approach: Signal::set() never invokes callbacks directly. It bumps the version, snapshots the subscriber list, and pushes a closure into the executor&#8217;s deferred callback queue. The executor drains this queue at the start of every flush, before polling any tasks.</p>
<p>Three states, two flags:</p>
<p>notifying = false, dirty = false → normal. Snapshot subscribers, push notification, set dirty.<br />
notifying = true              → re-entrant set during callback. Just set dirty, no new notification.<br />
dirty = true, notifying=false → notification already queued. No-op.</p>
<p>After callbacks complete: check dirty. If a re-entrant set() happened during the callback round, schedule a follow-up notification using a fresh subscriber snapshot (so newly-added subscribers from the callback round are included).</p>
<p>This covers every edge case: re-entrant set, subscribe/unsubscribe during callback iteration, scope drop during callback (cancelled flag is a Cell outside the RefCell, always writable), set-from-Drop (deferred to next flush via set_deferred()).</p>
<p>The tradeoff</p>
<p>A traditional reactive scheduler can run effects in topological order — dependencies before dependents, guaranteeing each memo recomputes at most once. An async executor runs tasks in whatever order they wake up. If two effects both read a dirty memo, they might each trigger its recomputation (the second read sees it&#8217;s already clean and skips the work, but the first poll of each effect triggers the check).</p>
<p>Correctness is preserved — version checking + lazy memo recompute guarantees eventual consistency. But optimality is best-effort, not guaranteed.</p>
<p>For UI frame-level reactivity this is fine. For a compiler&#8217;s incremental analysis it probably isn&#8217;t. I think the simplicity trade is worth it for most applications, but I&#8217;d be curious to hear counterarguments.</p>
<p>Why bother?</p>
<p>If you squint, reactive programming and async programming are solving the same problem from different directions. One suspends computation waiting for data changes; the other suspends computation waiting for I/O. The primitives overlap almost completely. The question isn&#8217;t &#8220;can you build reactivity on async&#8221; — it&#8217;s &#8220;why wouldn&#8217;t you?&#8221;</p>
<p>The only genuinely novel piece needed is a safe way to fire subscriber callbacks without re-entrancy. Everything else is already in the language.</p>
<p>I built a working implementation of this (~1800 lines across two crates, #![forbid(unsafe_code)], zero external deps for the signal layer). I’d genuinely love technical feedback — especially on:</p>
<ul>
<li>Whether the lack of topological ordering has bitten anyone in real UI projects, or if it’s mostly a theoretical concern.</li>
<li>Whether there’s a simpler alternative to the generational slot table I’m using for executor routing.</li>
</ul>
<p>If I’ve missed an edge case, or if any of the tradeoffs feel wrong to you, I’m all ears. This is still my own learning process, and I’d rather get corrected now than find out later.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/what-if-reactive-effects-are-just-pausable-async-tasks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Fix Flutter Web Release Errors During Build</title>
		<link>https://codango.com/how-to-fix-flutter-web-release-errors-during-build/</link>
					<comments>https://codango.com/how-to-fix-flutter-web-release-errors-during-build/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Tue, 12 May 2026 17:20:44 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/how-to-fix-flutter-web-release-errors-during-build/</guid>

					<description><![CDATA[Introduction If you&#8217;re experiencing issues when executing flutter run --release or flutter build web, despite the app running smoothly in development mode using flutter run -d chrome, you’re not alone. <a class="more-link" href="https://codango.com/how-to-fix-flutter-web-release-errors-during-build/">Continue reading <span class="screen-reader-text">  How to Fix Flutter Web Release Errors During Build</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<h2>Introduction</h2>
<p>If you&#8217;re experiencing issues when executing <code>flutter run --release</code> or <code>flutter build web</code>, despite the app running smoothly in development mode using <code>flutter run -d chrome</code>, you’re not alone. This is a common dilemma that many Flutter developers face when transitioning their app from a debug build to a release build. In this article, we&#8217;ll explore why these errors occur and provide step-by-step solutions to resolve them.</p>
<h2>Why Are You Facing Errors in Flutter Web Release?</h2>
<p>When you attempt to create a release build using Flutter for the web, several factors could be causing errors. These include:</p>
<ul>
<li>
<strong>Dependencies Mismatch</strong>: Conflicts with certain package versions might only present themselves in release mode.</li>
<li>
<strong>Incorrect Environment Configurations</strong>: Sometimes, configurations for web releases differ from those in your development environment.</li>
<li>
<strong>Code Compilation Issues</strong>: Certain code elements may function in a debug environment but can break during a release build due to optimizations or tree-shaking mechanisms.</li>
<li>
<strong>CORS Policy Issues</strong>: If your web app requires resources from different origins, you may run into CORS policy issues that appear in production but not in development.</li>
</ul>
<p>Next, let’s delve into the solutions you can try to rectify these issues.</p>
<h2>Step-by-Step Solutions to Fix Flutter Web Release Errors</h2>
<h3>1. <strong>Upgrade Flutter SDK</strong><br />
</h3>
<p>Before trying any complex solutions, ensure your Flutter SDK is up-to-date. Run the following command:</p>
<pre><code>flutter upgrade
</code></pre>
<p>Check your current Flutter version using:</p>
<pre><code>flutter --version
</code></pre>
<p>This ensures that any bug fixes or improvements related to the release mode are included.</p>
<h3>2. <strong>Check Your Dependencies</strong><br />
</h3>
<p>Ensure that your <code>pubspec.yaml</code> file contains compatible versions of all packages. You can upgrade all your packages to the latest compatible versions by running:</p>
<pre><code>flutter pub upgrade
</code></pre>
<p>After upgrading, don&#8217;t forget to run:</p>
<pre><code>flutter pub get
</code></pre>
<p>This ensures that any new dependencies are correctly added.</p>
<h3>3. <strong>Inspect Your Code for Errors</strong><br />
</h3>
<p>To efficiently identify issues in your code:</p>
<ul>
<li>Comment out parts of your app to determine which sections are failing.</li>
<li>Pay particular attention to asynchronous operations, external API calls, and other functionalities that may not trigger errors in the debug mode.</li>
</ul>
<h3>4. <strong>Using Flutter Clean</strong><br />
</h3>
<p>If you&#8217;ve tried changing packages or configurations but are still facing release issues, performing a clean build often helps. Use:</p>
<pre><code>flutter clean
</code></pre>
<p>Then try rebuilding:</p>
<pre><code>flutter build web
</code></pre>
<p>This command removes the build directory and ensures you start fresh.</p>
<h3>5. <strong>Check Browser Console for Errors</strong><br />
</h3>
<p>Open the developer console in the Chrome browser (using F12 or right-click and select &#8216;Inspect&#8217;) to see any JavaScript errors or warnings being logged when your web app runs. These messages may provide clues as to what’s wrong.</p>
<h3>6. <strong>Adjust Build Configurations</strong><br />
</h3>
<p>Sometimes, specific build configurations need to be set for optimal success:</p>
<ul>
<li>Open your <code>web/index.html</code> file and ensure you have the correct base href set if you&#8217;re deploying to a subdirectory.</li>
<li>Check your asset files path to ensure they&#8217;re correctly referenced.</li>
</ul>
<h3>7. <strong>Review the Flutter Web Configuration</strong><br />
</h3>
<p>Ensure that your <code>web</code> folder has all the necessary files (including <code>index.html</code>, <code>favicon.png</code>, etc.). Sometimes missing files can lead to errors during the release process.</p>
<h3>Frequently Asked Questions (FAQ)</h3>
<h4>Q1: Why does my app work fine in debug mode but fails in release mode?</h4>
<p>A1: Debug mode runs in an environment optimized for development, often ignoring error-checking mechanisms that a release build adheres to. This can expose hidden bugs.</p>
<h4>Q2: How can I know if my package versions are compatible?</h4>
<p>A2: Use the <code>pubspec.lock</code> file for a record of what versions are currently being used. You can also check the package&#8217;s repository for compatibility information.</p>
<h4>Q3: What should I do if performance is significantly lower in release mode?</h4>
<p>A3: Ensure that all images and assets are properly optimized for the web and consider using lazy loading for images to improve load times.</p>
<h2>Conclusion</h2>
<p>Addressing the errors occurring during Flutter web release builds can seem daunting, but by following the outlined steps and tips above, you should be able to identify and fix the underlying issues. Whether it&#8217;s updating dependencies, cleaning your project, or inspecting your code, tackling the problem methodically will get your web application up and running in release mode. Always review the console for output and logs as they can offer significant insights that aid in your debugging efforts. Happy coding!</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/how-to-fix-flutter-web-release-errors-during-build/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Build a Headless Shopify Store with Next.js in 2026</title>
		<link>https://codango.com/how-to-build-a-headless-shopify-store-with-next-js-in-2026/</link>
					<comments>https://codango.com/how-to-build-a-headless-shopify-store-with-next-js-in-2026/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Tue, 12 May 2026 10:01:35 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/how-to-build-a-headless-shopify-store-with-next-js-in-2026/</guid>

					<description><![CDATA[Liquid syntax error: Variable &#8216;{{% raw %}&#8217; was not properly terminated with regexp: /}}/]]></description>
										<content:encoded><![CDATA[<p>Liquid syntax error: Variable &#8216;{{% raw %}&#8217; was not properly terminated with regexp: /}}/</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/how-to-build-a-headless-shopify-store-with-next-js-in-2026/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Compass v1.1.0 · we shipped a memory plugin that catches its own consumption drift</title>
		<link>https://codango.com/compass-v1-1-0-%c2%b7-we-shipped-a-memory-plugin-that-catches-its-own-consumption-drift-2/</link>
					<comments>https://codango.com/compass-v1-1-0-%c2%b7-we-shipped-a-memory-plugin-that-catches-its-own-consumption-drift-2/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Tue, 12 May 2026 10:01:01 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/compass-v1-1-0-%c2%b7-we-shipped-a-memory-plugin-that-catches-its-own-consumption-drift-2/</guid>

					<description><![CDATA[Compass v1.1.0 · the recall consumption fix We shipped nautilus-compass v1.1.0 12 hours after v1.0.0. v1.0.0 was the public stable cut. v1.1.0 fixes a class of failure that v1.0.0 surfaces <a class="more-link" href="https://codango.com/compass-v1-1-0-%c2%b7-we-shipped-a-memory-plugin-that-catches-its-own-consumption-drift-2/">Continue reading <span class="screen-reader-text">  Compass v1.1.0 · we shipped a memory plugin that catches its own consumption drift</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<h1>
<p>  Compass v1.1.0 · the recall consumption fix<br />
</p></h1>
<p>We shipped <a href="https://github.com/chunxiaoxx/nautilus-compass" rel="noopener noreferrer">nautilus-compass v1.1.0</a><br />
12 hours after v1.0.0. v1.0.0 was the public stable cut. v1.1.0 fixes a<br />
class of failure that v1.0.0 surfaces but does not catch · which we<br />
caught in our own usage 5 hours after launch.</p>
<h2>
<p>  The bug we caught in production<br />
</p></h2>
<p>A sister Claude Code dialog was supposed to publish a long-form article<br />
to wechat using a 6-step quality pipeline (audit-gate, xhs-cards-embed,<br />
specific account login flow). The pipeline was documented in cross-session<br />
memory · a file called <code>publisher_quality_pipeline_20260430.md</code>.</p>
<p>Compass recall fired correctly · the file appeared in the agent&#8217;s<br />
<code>UserPromptSubmit</code> hook output:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight markdown"><code>&#x1f7e2; [3h old] memory/publisher_quality_pipeline_20260430.md
       audit-gate / xhs-cards-embed / wxid · v6 必须先过 critic 6 维评分再发布
</code></pre>
</div>
<p>The agent saw the title. Saw the 80-character description. Acted. <strong>It<br />
did not Read the file body.</strong> The actual rules — <em>how</em> to walk audit-gate,<br />
<em>which</em> wxid, <em>what</em> xhs-cards-embed structure looks like — those rules<br />
were in the body. None of them entered the agent&#8217;s working context.</p>
<p>The agent then reproduced exactly the failure mode the file was written<br />
to prevent: ad-hoc <code>_tmp_publish_v8.cjs</code> scripts, no critic round, wrong<br />
login path.</p>
<p>The user&#8217;s diagnosis was sharp:</p>
<blockquote>
<p>compass 召回到了 · 我没消费 · 这是 agent 层的人格漂移 · 不是 compass 本身的失败</p>
</blockquote>
<p>That&#8217;s half right. Recall surfaced the right file. The agent failed to<br />
consume. But the <strong>shape of the recall response made the failure easy</strong> —<br />
we returned title + 120-char description. Easy to skim. Easy to assume<br />
you have read it when you have only read the index.</p>
<p>This is structural. Not the agent&#8217;s fault.</p>
<h2>
<p>  The three-layer fix in v1.1.0<br />
</p></h2>
<h3>
<p>  v0 · embed body in top-3 hits<br />
</p></h3>
<p>Top-3 recall hits now embed the first 800 characters of post-frontmatter<br />
body in an indented <code>│</code> block:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight markdown"><code>&#x1f7e2; score=0.84 · [3h old] memory/publisher_quality_pipeline_20260430.md
       audit-gate / xhs-cards-embed / wxid · v6 必须先过 critic 6 维评分
       │ # Publisher quality pipeline
       │
       │ Six-step pipeline mandatory before publishing to wechat:
       │ 1. audit-gate · V6 critic checks against 6 dimensions ...
       │ 2. xhs-cards-embed · embed cards into article body via ...
       │ 3. wxid login flow · use wxid <span class="sb">`chunxiaox`</span> not openid_of_first_follower
       │ ...
       │ … (+1273 more · Read publisher_quality_pipeline_20260430.md for rest)
</code></pre>
</div>
<p>The agent now has the rules in its working context. No additional <code>Read</code><br />
tool call required. Tail hits 4..K stay header-only to keep the response<br />
bounded (~3KB total).</p>
<h3>
<p>  v1 · embed past-mistake body in anti-anchor alerts<br />
</p></h3>
<p>Compass&#8217;s drift detector matches the current prompt against 35 negative<br />
anchors learned from prior mistakes (<code>"我猜应该是这样 · 反正用户不查"</code>,<br />
<code>"假装上次说定了的方案 · 用户应该忘了"</code>, &#8230;).</p>
<p>Until v1.1.0 the alert just said: <em>&#8220;matched anti-anchor X with cos=0.625&#8221;</em>.<br />
Same problem as v0 — label visible, body invisible, agent shrugs.</p>
<p>v1.1.0 alerts now embed body from the most-relevant past lesson session.<br />
Two-tier match: substring 6-gram against the anchor + lesson-type<br />
frontmatter (Tier 1, precise) · falls back to recent <code>drift!=green</code><br />
sessions (Tier 2, the agent&#8217;s own self-reported slip-ups). Every alert<br />
becomes actionable, not decorative.</p>
<h3>
<p>  v2 · detect &#8220;recall fired but not consumed&#8221;<br />
</p></h3>
<p>The most direct signal: did the agent actually open any of the files<br />
recall surfaced?</p>
<p><code>recall_consumption.py</code> (new module) walks back through the live session<br />
jsonl file, finds N most-recent recall blocks, extracts memory file<br />
paths, then checks subsequent assistant turns for matching <code>Read</code> tool<br />
calls. If recall surfaced N paths and 0 got read, that is the failure<br />
signature.</p>
<p>Wired into:</p>
<ul>
<li>
<code>drift_check</code> MCP tool result — runs even when the BGE daemon is<br />
unreachable, since the audit is pure file traversal</li>
<li>
<code>mid_session_hook</code> every 25 tool calls — only nags when ≥3 unconsumed<br />
AND ratio &lt; 0.3 (real signal, not noise)</li>
</ul>
<p>Tested on a 130MB / 32k-line session: 41 recall hits surfaced, 0 consumed.<br />
Smoking gun for &#8220;label != consumption&#8221; drift.</p>
<h2>
<p>  V7 v0.2 · the governance plan that scales without templates<br />
</p></h2>
<p>v1.0.0 shipped a thin V7 governance layer with three tools:<br />
<code>governance_dispatch</code> (fan-out router), <code>governance_audit</code> (cross-agent<br />
fake-closure scanner), <code>governance_lock_check</code> (L0 hash lock for the<br />
immutable core). 13 MCP tools total.</p>
<p>v0.1 dispatch worked but it was a fan-out router — given <code>channels=<br />
[dev.to, x, github]</code> it produced one bounty per channel via static dict<br />
lookup. A user asked the right question:</p>
<blockquote>
<p>千行百业有各种不同的任务类型永远不可能覆盖。</p>
</blockquote>
<p>Right. Templates cannot cover the long tail of industries. The platform<br />
side already solved this for <em>publishing</em> — channel adapters + anchor<br />
pack registry — so adding a new channel or vertical = data change, not<br />
code change.</p>
<p>v1.1.0 brings the same idea to <em>decomposition</em>. The new<br />
<code>governance_plan</code> MCP tool reads two file-exported registries:</p>
<ol>
<li>
<code>_platform_registry/agents_capabilities.json</code> — what each executor<br />
declares it can do (id, outputs, optional domains, optional anchor<br />
packs)</li>
<li>
<code>_platform_registry/anchor_packs_phases.json</code> — per-domain DAG of<br />
phases, each phase says <code>requires_capability</code> and <code>depends_on</code>
</li>
</ol>
<p>For each phase, V7 ranks executors by capability score (+10 capability<br />
match, +5 domain match, +3 anchor pack match), picks the highest, emits<br />
a queue file with <code>depends_on_phase_ids</code> so platform-side cron mints<br />
bounties in the right order.</p>
<p>Verified on two domains:</p>
<ul>
<li>
<code>marketing/dev-tools</code> → 4 phases routed V5/V5/V5/Kairos</li>
<li>
<code>caishen-finance/audit</code> → 5 phases · V6 wins for <code>numeric-audit</code><br />
(V5 doesn&#8217;t declare it · V5 takes write+publish)</li>
</ul>
<p>Adding <code>medical/literature-review</code> next: 1 row in <code>platform_anchor_packs</code></p>
<ul>
<li>1 row in <code>platform_agents.metadata.capabilities[]</code>. Zero V7 source<br />
change. Zero MCP tool surface change.</li>
</ul>
<h2>
<p>  What stayed unchanged · the eval headlines<br />
</p></h2>
<p>Eval numbers are still the v1.0.0 locked numbers from 2026-05-08:</p>
<div class="table-wrapper-paragraph">
<table>
<thead>
<tr>
<th>Metric</th>
<th>nautilus-compass</th>
<th>best public baseline</th>
</tr>
</thead>
<tbody>
<tr>
<td>LongMemEval-S (n=500)</td>
<td><strong>56.6%</strong></td>
<td>Zep 55-60% (different judge)</td>
</tr>
<tr>
<td>EverMemBench-Dynamic Run 1</td>
<td>
<strong>44.4%</strong> (n=500)</td>
<td>MemOS 42.55</td>
</tr>
<tr>
<td>EverMemBench-Dynamic Run 2</td>
<td>
<strong>47.3%</strong> (n=497)</td>
<td>—</td>
</tr>
<tr>
<td>Drift detector ROC AUC (held-out)</td>
<td><strong>0.83</strong></td>
<td>—</td>
</tr>
<tr>
<td>Reproduction cost</td>
<td>
<strong>$3.50</strong> end-to-end</td>
<td>$50+ for GPT-4o-judge stacks</td>
</tr>
</tbody>
</table>
</div>
<p>v1.1.0 doesn&#8217;t move the eval numbers. It moves the <em>consumption</em><br />
numbers — the ratio of recall hits whose body actually lands in the<br />
agent&#8217;s working context. We do not have a clean benchmark for that yet<br />
(suggestions welcome) but in our own sessions it went from &#8220;skim the<br />
title and proceed&#8221; to &#8220;rules-in-context by default.&#8221;</p>
<h2>
<p>  Try it<br />
</p></h2>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>pip <span class="nb">install </span>nautilus-compass<span class="o">==</span>1.1.0
<span class="c"># or</span>
npm <span class="nb">install </span>nautilus-compass@1.1.0
</code></pre>
</div>
<p>Two papers on arxiv (drift detection + memory pipeline). 228 pytests<br />
all green. MIT (anchors CC0).</p>
<p>Repo: <a href="https://github.com/chunxiaoxx/nautilus-compass" rel="noopener noreferrer">github.com/chunxiaoxx/nautilus-compass</a></p>
<p>In-browser drift demo (no install): <a href="https://huggingface.co/spaces/chunxiaox/nautilus-compass" rel="noopener noreferrer">huggingface.co/spaces/chunxiaox/nautilus-compass</a></p>
<h2>
<p>  Postscript · what we believe<br />
</p></h2>
<blockquote>
<p>Recall != consumption · 看正文才算消费 · 不然命中等于零</p>
</blockquote>
<p>Long-running agents drift. They forget rules they read three sessions<br />
ago. They reproduce mistakes someone else already paid for. The fix is<br />
not a smarter model · it is making the rules unmissably present in the<br />
working context, then auditing whether they were actually consumed,<br />
then making the audit cheap enough to run every 25 tool calls.</p>
<p>That is what v1.1.0 ships.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/compass-v1-1-0-%c2%b7-we-shipped-a-memory-plugin-that-catches-its-own-consumption-drift-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Remove text and watermarks from any image — one API call</title>
		<link>https://codango.com/remove-text-and-watermarks-from-any-image-one-api-call/</link>
					<comments>https://codango.com/remove-text-and-watermarks-from-any-image-one-api-call/#respond</comments>
		
		<dc:creator><![CDATA[Codango Admin]]></dc:creator>
		<pubDate>Tue, 12 May 2026 10:00:58 +0000</pubDate>
				<category><![CDATA[Codango® Blog]]></category>
		<guid isPermaLink="false">https://codango.com/remove-text-and-watermarks-from-any-image-one-api-call/</guid>

					<description><![CDATA[Remove text and watermarks from any image — one API call Most image-cleanup APIs make you do half the work yourself. You draw a mask, you upload the mask, you <a class="more-link" href="https://codango.com/remove-text-and-watermarks-from-any-image-one-api-call/">Continue reading <span class="screen-reader-text">  Remove text and watermarks from any image — one API call</span><span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<h1>
<p>  Remove text and watermarks from any image — one API call<br />
</p></h1>
<p>Most image-cleanup APIs make you do half the work yourself. You draw a mask, you upload the mask, you cross your fingers. We got tired of that. <code>POST /v1/image/remove-text</code> finds the text for you, erases it, and hands back a clean image. One call. One URL. Done.</p>
<h2>
<p>  What it does<br />
</p></h2>
<p><code>remove-text</code> is an auto-detect-and-erase pipeline for visible text in images. Point it at any public image URL and it segments out the text regions on its own — watermarks, captions, signage, burned-in timestamps, the corner-of-the-frame copyright text — then inpaints what was underneath using the surrounding image context. The output is the same image, minus the text, with the rest of the scene left intact.</p>
<p>The endpoint is <code>POST /v1/image/remove-text</code>. The request is JSON. The response is the cleaned image. There is nothing else to configure for the default path.</p>
<p>If you want finer control, three fields are exposed:</p>
<ul>
<li>
<code>image_url</code> — public URL of the source image. Required.</li>
<li>
<code>regions</code> — an optional list of bounding boxes. Pass these if you want removal restricted to specific parts of the image instead of the whole frame. Useful when there is legitimate text you want to keep (a sign behind the subject, a label on a product) and text you want gone (a watermark over the foreground).</li>
<li>
<code>preserve_layout</code> — boolean, defaults to <code>true</code>. With it on, the surrounding objects, edges, and structure stay where they are; the inpainting only fills the text region and blends to the local context. Turn it off only if you specifically want a freer regeneration of the masked area.</li>
</ul>
<p>That is the whole surface. No mask uploads. No multi-step flow where you call a detection endpoint, post-process the boxes, and then call a separate inpainting endpoint. The detection and the inpainting happen on our side, in one round trip.</p>
<p>A few things worth being explicit about, since the FACTS block keeps me honest:</p>
<ul>
<li>It targets <strong>visible text</strong>. Watermarks, captions, signage, timestamps — the kinds of overlays that appear in pixels, not metadata.</li>
<li>It works on <strong>arbitrary backgrounds</strong>. The inpainting uses surrounding context, so it handles sky, skin, fabric, asphalt, foliage — whatever happens to be behind the text.</li>
<li>It is built so you do not have to <strong>author the mask</strong>. That is the whole point of the detection step happening on our side.</li>
</ul>
<p>If you have used image-cleanup tooling before, you will notice the request body is almost empty. That is deliberate.</p>
<h2>
<p>  Why we built it<br />
</p></h2>
<p>Every team that ships images at scale ends up needing this. Stock-photo workflows. Archive digitization. Re-use of legacy creative. Security-footage ingestion. Marketplaces scraping seller-supplied photos. The pattern is always the same: somebody, somewhere in the pipeline, baked text into the pixels, and now you need it gone before the image moves to the next stage.</p>
<p>The existing options are not great. The traditional path is: run a detector, get bounding boxes, draw a mask, post the mask plus the original image to an inpainting endpoint, hope the seams match. That is two or three services, two or three round trips, and a glue layer you now own. Most rival APIs expose only the inpainting half and expect you to bring the mask. Which is fine if you are a Photoshop user doing one image. It is a problem if you are a backend.</p>
<p>Our angle is simple: <strong>detect and remove in one call</strong>. We run our own segmentation step on the image, build the mask from the detected text regions, and then inpaint the masked area with surrounding context — all server-side, all in the same request. You do not see the mask. You do not need to see the mask. You get the finished image back.</p>
<p>A few design choices fall out of that:</p>
<ul>
<li>
<strong>No mask upload path.</strong> We deliberately did not ship a &#8220;bring your own mask&#8221; mode at launch. The point of the API is that you do not need one. If you have very specific requirements about <em>where</em> removal can happen, that is what <code>regions</code> is for — coarse bounding boxes are enough to constrain the work, and far easier to author than a pixel-precise mask.</li>
<li>
<strong><code>preserve_layout</code> defaults to on.</strong> The most common failure mode of generative inpainting is that it cheerfully invents new objects in the cleared area. For text removal specifically, you almost never want that — you want the <em>same scene</em>, minus the text. So that is the default behavior, not an opt-in.</li>
<li>
<strong>Single endpoint, single response.</strong> No job IDs, no polling, no callback URLs for the default case. You call it, you get the image. We host the infrastructure so you do not have to figure out batch queues for what is, conceptually, a one-shot transform.</li>
</ul>
<p>The thing we want to make boring is the part that is usually annoying: getting a clean image out of a dirty one.</p>
<h2>
<p>  Quickstart<br />
</p></h2>
<p>The minimal call is one <code>curl</code>. Drop your API key in, point <code>image_url</code> at any reachable image, and you are done.
</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>curl <span class="nt">-X</span> POST https://api.pixelapi.dev/v1/image/remove-text <span class="se"></span>
  <span class="nt">-H</span> <span class="s2">"Authorization: Bearer YOUR_API_KEY"</span> <span class="se"></span>
  <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se"></span>
  <span class="nt">-d</span> <span class="s1">'{"image_url": "https://example.com/source.jpg"}'</span>
</code></pre>
</div>
<p>Same thing in Python using <code>requests</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="kn">import</span> <span class="n">os</span>
<span class="kn">import</span> <span class="n">requests</span>

<span class="n">API_KEY</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">[</span><span class="sh">"</span><span class="s">PIXELAPI_KEY</span><span class="sh">"</span><span class="p">]</span>

<span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
    <span class="sh">"</span><span class="s">https://api.pixelapi.dev/v1/image/remove-text</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">headers</span><span class="o">=</span><span class="p">{</span>
        <span class="sh">"</span><span class="s">Authorization</span><span class="sh">"</span><span class="p">:</span> <span class="sa">f</span><span class="sh">"</span><span class="s">Bearer </span><span class="si">{</span><span class="n">API_KEY</span><span class="si">}</span><span class="sh">"</span><span class="p">,</span>
        <span class="sh">"</span><span class="s">Content-Type</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">application/json</span><span class="sh">"</span><span class="p">,</span>
    <span class="p">},</span>
    <span class="n">json</span><span class="o">=</span><span class="p">{</span>
        <span class="sh">"</span><span class="s">image_url</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">https://example.com/source.jpg</span><span class="sh">"</span><span class="p">,</span>
    <span class="p">},</span>
    <span class="n">timeout</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">resp</span><span class="p">.</span><span class="nf">raise_for_status</span><span class="p">()</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">resp</span><span class="p">.</span><span class="nf">json</span><span class="p">()</span>
<span class="nf">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</code></pre>
</div>
<p>That covers the default case: full-image scan, layout preserved, text gone.</p>
<p>If you want to scope the removal — say, you only want to clean the bottom-right corner where the timestamp lives, and you want to leave the rest of the image untouched even if there happens to be incidental text in it — pass <code>regions</code>:
</p>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
    <span class="sh">"</span><span class="s">https://api.pixelapi.dev/v1/image/remove-text</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">headers</span><span class="o">=</span><span class="p">{</span>
        <span class="sh">"</span><span class="s">Authorization</span><span class="sh">"</span><span class="p">:</span> <span class="sa">f</span><span class="sh">"</span><span class="s">Bearer </span><span class="si">{</span><span class="n">API_KEY</span><span class="si">}</span><span class="sh">"</span><span class="p">,</span>
        <span class="sh">"</span><span class="s">Content-Type</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">application/json</span><span class="sh">"</span><span class="p">,</span>
    <span class="p">},</span>
    <span class="n">json</span><span class="o">=</span><span class="p">{</span>
        <span class="sh">"</span><span class="s">image_url</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">https://example.com/cam-frame.jpg</span><span class="sh">"</span><span class="p">,</span>
        <span class="sh">"</span><span class="s">regions</span><span class="sh">"</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">{</span><span class="sh">"</span><span class="s">x</span><span class="sh">"</span><span class="p">:</span> <span class="mi">1500</span><span class="p">,</span> <span class="sh">"</span><span class="s">y</span><span class="sh">"</span><span class="p">:</span> <span class="mi">1000</span><span class="p">,</span> <span class="sh">"</span><span class="s">width</span><span class="sh">"</span><span class="p">:</span> <span class="mi">380</span><span class="p">,</span> <span class="sh">"</span><span class="s">height</span><span class="sh">"</span><span class="p">:</span> <span class="mi">60</span><span class="p">}</span>
        <span class="p">],</span>
        <span class="sh">"</span><span class="s">preserve_layout</span><span class="sh">"</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
    <span class="p">},</span>
    <span class="n">timeout</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span>
<span class="p">)</span>
</code></pre>
</div>
<p>And that is the API. There is no step three.</p>
<h2>
<p>  Use cases<br />
</p></h2>
<h3>
<p>  Cleaning up timestamps burned into security-camera frames<br />
</p></h3>
<p>If you operate any kind of CCTV or DVR pipeline, you know the problem. The camera firmware burns a timestamp directly into every frame — usually white text in a corner, sometimes with a black background block, sometimes not. The metadata is also in the file, so the burned-in copy is redundant. But the moment you want to do anything downstream — train a model on the frames, use the footage in an internal incident report, hand a snapshot to a customer — that timestamp is sitting there in the pixels and it cannot be turned off retroactively. Running each frame through <code>remove-text</code> with a <code>regions</code> box around the corner where the timestamp lives gives you a clean frame, with the rest of the scene unchanged. Wire it into your ingest path and the burned-in copy never leaves your pipeline. The metadata stays where it belongs — in the file headers — and the visual frame is yours to use.</p>
<h3>
<p>  Stripping captions off stock-photo previews you&#8217;ve licensed<br />
</p></h3>
<p>Stock-photo workflows are full of friction. You browse, you license, you download the high-resolution version — and the licensed copy is supposed to come without the preview watermark. In practice, half the asset systems we have talked to end up with watermarked previews mixed into their working folders, either because someone grabbed a comp earlier in the process, or because a partner sent a reference file by mistake, or because the asset got cached at the preview stage and the clean version never replaced it. For images you have legitimately licensed, <code>remove-text</code> lets you reclaim those preview copies without re-downloading from the source. Detection handles the irregular placement of caption strips — corner, diagonal, full-frame tile — and the inpainting fills the area using whatever is around it. You end up with a usable working file from an asset you already paid for.</p>
<h3>
<p>  Erasing brand markings before re-using your own product imagery in a new campaign<br />
</p></h3>
<p>Every brand team eventually hits this: a beautiful product photo from a previous campaign, where the photographer (or the agency, or the in-house designer) baked the campaign tagline or the old SKU label into the corner. Now you want to re-use the shot for a new campaign, and that old text is a non-starter. The traditional fix is a designer round-trip — open the file, clone-stamp the area, retouch the edges, save out, version, ship. For one image, fine. For two hundred, painful. <code>remove-text</code> handles the cleanup programmatically: point it at the originals, get back versions with the legacy markings gone, and let your designers spend their time on the new creative instead of erasing the old. With <code>preserve_layout</code> on, the product itself stays exactly where it was — only the text disappears.</p>
<h2>
<p>  Pricing<br />
</p></h2>
<p>Pricing is per-call, flat, no tiers to negotiate.</p>
<ul>
<li>
<strong>Credits per call:</strong> 16</li>
<li>
<strong>Price in INR:</strong> ₹0.011 per call</li>
<li>
<strong>Price in USD:</strong> $0.00013 per call</li>
</ul>
<p>That is the cleared-image, end-to-end price. Detection plus inpainting. No separate charge for the segmentation step. No surcharge for using the <code>regions</code> field. If the call succeeds, it costs 16 credits; if it fails, it does not.</p>
<p>At those numbers, a hundred thousand images is around ₹1,100 / $13. Most teams discover that the cost of running this in production is dwarfed by the cost of <em>not</em> running it — the manual cleanup hours, the back-and-forth with vendors over watermarked deliverables, the asset-management tickets that pile up because someone has to find a designer to redo a corner of a photo.</p>
<h2>
<p>  Try it<br />
</p></h2>
<p>Sign in at <strong><a href="https://pixelapi.dev/dashboard" rel="noopener noreferrer">https://pixelapi.dev/dashboard</a></strong> to get your API key. New accounts come with starter credits, so you can hit the endpoint with one of your own images before deciding anything.</p>
<p>Full reference for the request body, error codes, response format, and the <code>regions</code> and <code>preserve_layout</code> fields lives in the docs at <strong><a href="https://pixelapi.dev/docs" rel="noopener noreferrer">https://pixelapi.dev/docs</a></strong>.</p>
<p>If you ship images at any kind of scale, give <code>remove-text</code> a real workload — a folder of timestamps, a batch of legacy product shots, a directory of licensed previews — and see what comes back. The whole point of this endpoint is that there is nothing else to learn. One URL in, one clean image out.</p>]]></content:encoded>
					
					<wfw:commentRss>https://codango.com/remove-text-and-watermarks-from-any-image-one-api-call/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
