CLAUDE LABEN
SLACK — Claude TagがSlackでベータ提供。チャンネルで@Claudeにタスクを委譲し、ツール・データ・コードベースを接続できますSECURITY — Claude Codeにsandbox.credentials設定が追加。認証ファイルや秘密の環境変数の読み取りをブロックできますFIX — リモートMCPツール呼び出しの5分ハングを修正。応答なしで止まらずエラーで中断しますMCP — 組織向けMCPコネクタがOktaプロビジョニングに対応。初回ログインでゼロタッチ接続できますMODEL — Claude Fable 5は100万トークン文脈・常時アダプティブ思考・128K出力を備えますLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられますSLACK — Claude TagがSlackでベータ提供。チャンネルで@Claudeにタスクを委譲し、ツール・データ・コードベースを接続できますSECURITY — Claude Codeにsandbox.credentials設定が追加。認証ファイルや秘密の環境変数の読み取りをブロックできますFIX — リモートMCPツール呼び出しの5分ハングを修正。応答なしで止まらずエラーで中断しますMCP — 組織向けMCPコネクタがOktaプロビジョニングに対応。初回ログインでゼロタッチ接続できますMODEL — Claude Fable 5は100万トークン文脈・常時アダプティブ思考・128K出力を備えますLINEUP — 主力はOpus 4.8・Sonnet 4.6・Haiku 4.5。用途に応じて使い分けられます
記事一覧/Cowork
Cowork/2026-06-25中級

無人タスクのログが前日分を上書きしていた — コンテナの date が UTC を返していた話

Cowork のスケジュールタスクが書く日付別ログが、朝の実行で前日分を上書きしていました。原因はコンテナの date が UTC を返していたこと。切り分けの過程と、TZ 固定・追記化・検知までの恒久対策を実例で記録します。

Cowork27スケジュールタスク12タイムゾーンログトラブルシューティング36

朝、前日のログを確認しようとして手が止まりました。

2026-06-13.txt を開くと、そこにあるはずの夜間バッチの記録が消えていて、代わりにその日の朝に走ったタスクの一行だけが残っていたのです。

ファイルは確かに存在している。中身だけが入れ替わっている。最初はタスクが二重起動して片方が壊れたのかと疑いましたが、調べていくと、犯人はずっと素朴な場所にいました。コンテナの中の date です。

個人開発で複数のサイトを無人運用していると、こうした「静かにデータが欠ける」種類の不具合がいちばん怖いと感じています。エラーで止まってくれれば気づけます。けれど黙って上書きされると、失われたことにすら気づけません。

何が起きていたか — ログが消えるのではなく、別の日付に書かれていた

私のスケジュールタスクは、実行のたびに日付別のログを残す設計でした。骨格はこうです。

LOG_DIR="$WS/_updated_article_log/claudelab"
echo "[$(date +%H:%M)] 記事を1本公開: $TITLE" > "$LOG_DIR/$(date +%F).txt"

ローカルの Mac で動かしている分には、何の問題もありませんでした。Mac のタイムゾーンは日本時間だからです。

破綻したのは、同じスクリプトをクラウドのコンテナ上で無人実行に切り替えたときでした。コンテナの既定タイムゾーンは UTC です。日本時間との差は9時間。つまり、日本時間の朝8時に走るタスクは、UTC ではまだ前日の23時です。

# 日本時間 2026-06-13 08:00 にタスクが起動
$ date
Thu Jun 12 23:00:00 UTC 2026   # コンテナの中ではまだ「12日」
 
$ date +%F
2026-06-12                      # 当日のつもりが、前日の日付になる

ここに、もうひとつの落とし穴が重なりました。出力リダイレクトに >(上書き)を使っていたことです。

朝のタスクは「12日」のファイル名を計算し、> で開いて、前日の夜にきちんと書かれていた12日分のログを丸ごと消してから自分の一行を書き込んでいました。ログが消えたのではなく、間違った日付のファイルに、上書きモードで書かれていた。これが真相でした。

最初に疑ったこと、そして実際の原因

最初に疑ったのは二重起動でした。スケジューラが同じタスクを重ねて起動し、競合したのではないかと。

けれど実行履歴を見ると、起動は1日に想定どおりの回数しかありません。競合の痕跡もない。

次に疑ったのはファイルシステムの同期です。クラウド同期フォルダ越しに書いていたため、同期の遅延で古い版が復活したのではないかと。これも、ローカルとリモートのタイムスタンプを突き合わせて否定できました。

決め手は、消えたログのファイル名と中身のズレでした。2026-06-13.txt のはずの内容が 2026-06-12.txt に紛れ込んでいる。日付がきっかり一日ずれている。9時間の時差を思い出した瞬間に、すべてがつながりました。

切り分けで効いたのは、推測を増やす前に「実際に何が出力されるか」を一度だけ確認したことです。

# コンテナ内で、スクリプトが見ている日付をそのまま出す
$ TZ=Asia/Tokyo date +%F
2026-06-13
$ date +%F
2026-06-12

二つの値が違う。これで仮説は確定しました。コードのどこを直すかではなく、date が何を返しているかが問題だったのです。

恒久対策 — タイムゾーンを固定し、追記にし、消えたら気づけるようにする

直し方は三段構えにしました。一つでは不十分だと考えたからです。

第一に、日付の計算でタイムゾーンを明示します。 これが根本原因への対処です。

# 悪い例: コンテナの既定(UTC)に依存する
DAY="$(date +%F)"
 
# 良い例: 日本時間で固定する
DAY="$(TZ=Asia/Tokyo date +%F)"

スクリプトの先頭で export TZ=Asia/Tokyo を一度宣言しておけば、以降の date 呼び出しすべてに効きます。タスクごとに書き忘れる余地を消せるので、私はこちらを好んでいます。

#!/usr/bin/env bash
set -euo pipefail
export TZ=Asia/Tokyo   # この行を入れた瞬間に、以降の date は全て日本時間
 
LOG_DIR="$WS/_updated_article_log/claudelab"
mkdir -p "$LOG_DIR"

第二に、上書きをやめて追記にします。 同じ日に複数回走っても記録が積み上がるようにするためです。

# 悪い例: 同じ日の2本目の実行が1本目を消す
echo "[$(date +%H:%M)] $MSG" > "$LOG_DIR/$DAY.txt"
 
# 良い例: その日の記録を積み上げる
echo "[$(date +%H:%M)] $MSG" >> "$LOG_DIR/$DAY.txt"

たとえタイムゾーンの修正を入れ忘れた未来の自分がいても、追記であれば「別の日付に紛れ込む」ことはあっても「既存の記録を消す」ことは起きません。被害の上限を下げておく、という発想です。

第三に、異常を検知できるようにします。 静かに壊れる不具合は、静かなままにしないことがいちばんの対策です。

# その日のログが、実行後に空でないことを確認する
DAY="$(TZ=Asia/Tokyo date +%F)"
LOG="$LOG_DIR/$DAY.txt"
 
if [ ! -s "$LOG" ]; then
  echo "WARN: 本日($DAY)のログが空です。タイムゾーンか書き込み先を確認してください" >&2
fi
 
# ファイル名の日付と、中身の先頭行の日付が一致するかを軽く点検する
head -1 "$LOG" | grep -q "$(TZ=Asia/Tokyo date +%H)" ||   echo "NOTE: 直近のログ時刻が現在時刻と離れています" >&2

無音で不発に終わるタスクを外側から見張る考え方は、スケジュール生成が無音で不発に終わったことに気づく仕組みでも書きました。今回のログ上書きは、その「気づけない失敗」の一種でした。

なぜローカルでは一度も再現しなかったのか

この不具合がやっかいだったのは、開発環境では絶対に起きないことでした。

手元の Mac はタイムゾーンが日本時間です。datedate +%F も常に正しい日付を返します。何度試しても再現しない。けれど無人のコンテナに移した瞬間に、環境のタイムゾーンという見えない前提が変わり、同じコードが別の振る舞いをしました。

私自身、個人開発の現場でこの一件に時間を取られました。ここから学んだのは、時刻に依存する処理は「どのタイムゾーンで動くか」を環境任せにしてはいけないということです。ローカルとコンテナで暗黙の前提が食い違うと、テストをすり抜けて本番でだけ壊れます。

同じ理由で、コンテナと手元で挙動が割れる落とし穴は他にもあります。クローンが古いまま判断材料になってしまう件は浅いクローンが古いまま判断に使われる前にリフレッシュするに、無人タスクが黙って止まる側の対処はCowork スケジュールタスクが黙って止まる理由と自動復帰の作り方にまとめてあります。

もうひとつ、混同しやすい点を補足しておきます。スケジューラが「日本時間の朝8時に起動する」ことと、起動した先のシェルの date が日本時間を返すことは、別の話です。トリガーの時刻設定が正しくても、シェルの中身が UTC のままなら、今回と同じズレが起きます。トリガーの時刻と、スクリプト内で時刻を計算するタイムゾーンは、それぞれ独立して合わせる必要があります。

次に同じ轍を踏まないために

時刻を使うスクリプトを書いたら、push する前に一行だけ確認するようにしました。

# 「環境の date」と「意図したタイムゾーンの date」がズレていないか
diff <(date +%F) <(TZ=Asia/Tokyo date +%F) && echo "OK: 同一" || echo "要注意: タイムゾーン差あり"

この一行が 要注意 を返すなら、そのスクリプトはコンテナでだけ壊れる候補です。たった9時間の差が、一日分のログを消すには十分でした。

無人運用は、止まらないことよりも「壊れたときに気づけること」のほうが大切だと、今は考えています。同じように複数の自動タスクを回している方の、静かなデータ欠損を一つでも減らせれば幸いです。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Cowork2026-06-23
無人の記事生成タスクが『ほぼ同じ記事』を二度書く前に止める重複検出ゲート
Cowork のスケジュールタスクで毎日記事を生成していると、無人ゆえに数日前と中身がほぼ重なる記事を作ってしまいます。公開直前に slug の類似度と当日ログを照合して重複を止めるゲートを、実際に誤公開を防いだ実装とともにお届けします。
Cowork2026-06-21
Cowork の bash が『ファイルがありません』と言うのに Finder には見える理由
クラウド同期フォルダを Cowork に接続すると、bash からは実体のないプレースホルダが見え、cat が失敗します。オンデマンド実体化の仕組みと、自動化を取りこぼさないための設計パターンを実体験から解説します。
Cowork2026-06-13
Cowork スケジュールタスク運用の実際 — 朝のダイジェストと週次レポートを無人で回すまで
Claude Cowork のスケジュールタスクで定期実行・リマインダー・自動レポートを設定する手順を、cron 式の基本から無人実行に耐えるプロンプト設計、複数タスクの時間帯設計まで、運用で掴んだ勘所とともにお届けします。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →