<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Debugging on Margrop Blog</title>
		<link>https://blog.margrop.net/en/tag/debugging/</link>
		<description>Recent content in Debugging on Margrop Blog</description>
		<generator>Hugo</generator>
		<language>en-US</language>
		
		
		
		
			<lastBuildDate>Fri, 10 Jul 2026 08:00:00 +0800</lastBuildDate>
		
			<atom:link href="https://blog.margrop.net/en/tag/debugging/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>One Missing operator.write Took Down the Gateway: The OpenClaw Fallback Failure That Wasn&#39;t a Model Problem</title>
				<link>https://blog.margrop.net/en/post/openclaw-missing-operator-write-scope/</link>
				<pubDate>Fri, 10 Jul 2026 08:00:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/openclaw-missing-operator-write-scope/</guid>
				<description>&lt;p&gt;This incident looked like a model-provider outage at first. OpenClaw had just received three NewAPI-backed fallback models, but gateway-based model calls started failing with a provider authentication error. After peeling back the outer message, the real error was much more specific:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;missing scope: operator.write&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That string changed the direction of the investigation. The provider key was not the root problem. The NewAPI endpoint was not the root problem. The model names were not the root problem either. The failure lived inside OpenClaw&amp;rsquo;s gateway authorization path: when a model override was used, the gateway call switched into a backend/gateway-client mode, but did not force the request to use the already paired stored device identity. The device had &lt;code&gt;operator.write&lt;/code&gt;; the request simply did not carry the identity that could prove it.&lt;/p&gt;&#xA;&lt;p&gt;The shortest version is this: &lt;strong&gt;the badge existed, but this entrance did not scan it.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog.margrop.net/post-images/openclaw-missing-operator-write-scope/cover.png&#34; alt=&#34;AI-generated cover showing a gateway protected by two authorization locks&#34;&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>PhotoPrism Stuck for 5 Minutes on First Boot? A Postmortem on PHOTOPRISM_INIT=intel</title>
				<link>https://blog.margrop.net/en/post/photoprism-init-intel-stuck/</link>
				<pubDate>Sat, 13 Jun 2026 08:30:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/photoprism-init-intel-stuck/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR (The Short Version)&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;PHOTOPRISM_INIT: &amp;quot;intel&amp;quot;&lt;/code&gt; line in PhotoPrism&amp;rsquo;s Plus Docker image is &lt;strong&gt;not&lt;/strong&gt; just a flag to enable Intel hardware acceleration at runtime — it&amp;rsquo;s a one-shot &lt;strong&gt;system-level installer&lt;/strong&gt; that runs &lt;code&gt;apt-get dist-upgrade&lt;/code&gt; against &lt;code&gt;archive.ubuntu.com&lt;/code&gt; and then installs 8 Intel/VA-API packages before the main process is allowed to start. On a fresh container this takes &lt;strong&gt;5–10 minutes&lt;/strong&gt; (sometimes more), during which nothing inside the container listens on port &lt;code&gt;2342&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Meanwhile: &lt;code&gt;docker ps&lt;/code&gt; says &lt;code&gt;Up&lt;/code&gt;, Portainer is green, &lt;code&gt;ss -ltn&lt;/code&gt; on the host shows &lt;code&gt;:2342&lt;/code&gt; LISTEN — but your browser gets &lt;code&gt;ERR_CONNECTION_RESET&lt;/code&gt; / &lt;code&gt;Connection reset by peer&lt;/code&gt;. Because host-side &lt;code&gt;docker-proxy&lt;/code&gt; accepts the connection and then tries to forward to a port inside the container that has no listener, the kernel sends back an RST.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; just remove or empty that one line. If you already pass &lt;code&gt;/dev/dri/renderD128&lt;/code&gt; via &lt;code&gt;devices:&lt;/code&gt;, the host&amp;rsquo;s drivers and userland libraries are perfectly usable from the container — there&amp;rsquo;s nothing to &amp;ldquo;install&amp;rdquo; in there.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
			</item>
			<item>
				<title>OpenClaw TUI Keeps Repeating Itself? A Temporary Patch for Duplicate Thinking and Replies</title>
				<link>https://blog.margrop.net/en/post/openclaw-tui-duplicate-thinking-stream-patch/</link>
				<pubDate>Tue, 02 Jun 2026 10:42:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/openclaw-tui-duplicate-thinking-stream-patch/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;The short version&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;If OpenClaw TUI shows the same thinking block twice and repeats the final answer, do not immediately delete every session or rebuild every model provider. In many OpenAI-compatible setups, the real issue is a streaming compatibility edge case: the upstream stream emits normal &lt;code&gt;delta&lt;/code&gt; chunks and then an extra full &lt;code&gt;message&lt;/code&gt; tail. Some OpenClaw paths may aggregate both, so the TUI and the persisted session both end up with duplicated content.&lt;/p&gt;&#xA;&lt;p&gt;The practical temporary fix is to back up the local OpenClaw installation, add a conservative dedupe guard in the OpenClaw aggregation layer, restart the gateway, and verify with a unique marker that both the visible reply and the session file contain only one copy.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This is a privacy-safe incident note. All endpoints, model names, tokens, internal addresses, and session identifiers are replaced by placeholders. Use your own installation path and model identifiers when applying the workaround.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Double-Consumed Streaming: Debugging a NewAPI v1.0.0-rc.10 MiniMax Proxy Bug</title>
				<link>https://blog.margrop.net/en/post/newapi-streaming-duplicate-content-debugging/</link>
				<pubDate>Sun, 31 May 2026 18:00:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/newapi-streaming-duplicate-content-debugging/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;An AI Agent was producing duplicated replies in DingTalk — not two separate messages, but a single message whose content appeared twice. The root cause traced back to a streaming bug in NewAPI (the QuantumNous fork of OneAPI) v1.0.0-rc.10: when proxying MiniMax through the OpenAI Chat Completions protocol, the finish chunk contained &lt;strong&gt;both &lt;code&gt;delta.content&lt;/code&gt; and &lt;code&gt;message.content&lt;/code&gt;&lt;/strong&gt; with identical values. The Agent&amp;rsquo;s stream handler consumed both as &amp;ldquo;visible text,&amp;rdquo; concatenating the content twice. The fix was straightforward: switch the OpenClaw provider protocol from &lt;code&gt;openai-completions&lt;/code&gt; to &lt;code&gt;anthropic-messages&lt;/code&gt;, which OneAPI natively supports and where streaming behaves correctly.&lt;/p&gt;&#xA;&lt;p&gt;No internal IPs, tokens, model IDs, or private paths appear in this article. All configuration snippets have been sanitized.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
			</item>
			<item>
				<title>Why HermesAgent Would Not Reply in WeChat or WeCom: The Real Culprit Was a Local Relay With a 3-Second Timeout</title>
				<link>https://blog.margrop.net/en/post/hermesagent-wechat-wecom-relay-timeout-debugging/</link>
				<pubDate>Sun, 31 May 2026 08:00:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/hermesagent-wechat-wecom-relay-timeout-debugging/</guid>
				<description>&lt;h2 id=&#34;the-short-version&#34;&gt;The short version&lt;/h2&gt;&#xA;&lt;p&gt;This incident looked like a model problem or a broken messaging channel, but the real failure happened one layer lower: my local &lt;code&gt;relay&lt;/code&gt; cut the upstream request off after 3 seconds. That was fine for quick health checks, but it was wrong for real WeChat and WeCom turns, which often take longer to produce a complete answer from the NewAPI gateway. Once the relay disconnected too early, HermesAgent could only see &lt;code&gt;Connection error&lt;/code&gt;, &lt;code&gt;RemoteProtocolError&lt;/code&gt;, and then exhausted fallback attempts.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Mystery: Where Did That http_proxy Come From in My New Tmux Session?</title>
				<link>https://blog.margrop.net/en/post/tmux-zsh-http-proxy-mystery/</link>
				<pubDate>Sat, 30 May 2026 16:00:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/tmux-zsh-http-proxy-mystery/</guid>
				<description>&lt;h1 id=&#34;preface&#34;&gt;Preface&lt;/h1&gt;&#xA;&lt;p&gt;Today I ran into a truly bizarre problem: in a freshly created tmux session, &lt;code&gt;echo $http_proxy&lt;/code&gt; showed a valid proxy address. But I distinctly remember that my &lt;code&gt;.zshrc&lt;/code&gt; only defines two aliases — &lt;code&gt;proxy_on&lt;/code&gt; and &lt;code&gt;proxy_off&lt;/code&gt; — both of which require manual invocation and don&amp;rsquo;t run automatically.&lt;/p&gt;&#xA;&lt;p&gt;The weirdest part: my main shell shows &lt;code&gt;http_proxy&lt;/code&gt; as empty, but as soon as I enter tmux, it&amp;rsquo;s there. I spent nearly an hour tracking this down, so I&amp;rsquo;m documenting it for posterity.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Python App in macOS LaunchAgent Can&#39;t Reach the Internet? Here&#39;s the httpx Proxy Trap You Need to Know</title>
				<link>https://blog.margrop.net/en/post/macos-launchagent-python-httpx-proxy-no-route-to-host/</link>
				<pubDate>Sat, 30 May 2026 09:00:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/macos-launchagent-python-httpx-proxy-no-route-to-host/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;When a Python application using httpx with &lt;code&gt;trust_env=True&lt;/code&gt; runs inside a macOS LaunchAgent, it silently picks up the system proxy settings from &lt;code&gt;scutil --proxy&lt;/code&gt;. But the LaunchAgent process may not be able to reach that proxy server at all — resulting in &lt;code&gt;All connection attempts failed&lt;/code&gt; or &lt;code&gt;No route to host&lt;/code&gt; errors.&lt;/p&gt;&#xA;&lt;p&gt;The fix is one line: add &lt;code&gt;NO_PROXY=*&lt;/code&gt; to the LaunchAgent&amp;rsquo;s plist &lt;code&gt;EnvironmentVariables&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This article documents the full debugging journey: from discovering that my AI Agent&amp;rsquo;s WeChat Enterprise (WeCom) messages weren&amp;rsquo;t being replied to, through methodical proxy troubleshooting, to finally pinning down the root cause — macOS system proxy + LaunchAgent network isolation. We&amp;rsquo;ll dive deep into Python httpx source code, macOS proxy architecture, and the many gotchas of LaunchAgent runtime environments.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
			</item>
			<item>
				<title>Why My AI Assistant Repeated One Reply Four Times: Debugging an OpenClaw WeChat Channel Issue</title>
				<link>https://blog.margrop.net/en/post/openclaw-wechat-duplicate-reply-debugging/</link>
				<pubDate>Fri, 29 May 2026 11:24:29 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/openclaw-wechat-duplicate-reply-debugging/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Short version&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The symptom looked like a messaging-channel bug: an AI assistant connected to a personal chat channel appeared to repeat the same reply multiple times. The real bug was earlier in the chain. Before the reply ever reached the message-sending layer, the OpenClaw agent had already produced duplicated visible text. The useful fix was not to patch the chat sender blindly, but to split the path into transport, session, model-routing, and provider layers, then compare the OpenAI-compatible gateway path with the native provider path. Once the faulty compatible provider candidate was removed from the visible model set and the personal IM channel was pinned to the native provider, the same minimal prompt returned exactly once.&lt;/p&gt;&#xA;&lt;p&gt;This post is deliberately privacy-safe. It contains no real internal addresses, account IDs, tokens, session IDs, personal chat identifiers, or private file paths. Configuration examples use placeholders. The value is the debugging method, not the private environment.&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
			</item>
	</channel>
</rss>
