[{"data":1,"prerenderedAt":236},["ShallowReactive",2],{"content-/analyst-target-fetch-failure-line-notification":3,"all-pages-for-dir":214,"related-/analyst-target-fetch-failure-line-notification":215,"og-image-/analyst-target-fetch-failure-line-notification":235},{"id":4,"title":5,"body":6,"category":193,"concepts":194,"description":195,"extension":196,"meta":197,"navigation":198,"ogImage":194,"path":199,"project_name":200,"published":201,"publishedAt":202,"seo":203,"source":204,"stem":205,"tags":206,"todo":194,"unpublished":201,"updatedAt":194,"__hash__":213},"pages/2026-10/2026-10-23/analyst-target-fetch-failure-line-notification.md","LINE通知の「1年後目標」がおかしかった原因は、目標株価の取得失敗だった",{"type":7,"value":8,"toc":186},"minimark",[9,13,17,22,25,31,34,38,41,77,80,83,86,90,93,98,101,111,114,119,123,126,129,138,141,156,159,162,171,174,182],[10,11,5],"h1",{"id":12},"line通知の1年後目標がおかしかった原因は目標株価の取得失敗だった",[14,15,16],"p",{},"10月23日の朝は、前日分の /make-diary を回していた。\n決算データの取り込みと保有銘柄ニュースの記事づくりを委譲先に任せ、終わるのを待っていたところで、定期実行の LINE 通知が目に留まった。",[18,19,21],"h2",{"id":20},"_1年後目標の数字に引っかかった","「1年後目標」の数字に引っかかった",[14,23,24],{},"家族の証券口座のポートフォリオ通知には、アナリストの目標株価から計算した「1年後目標」の行がある。\nその値が、どうも変に見えた。\nそこで Claude Code にそのまま聞いた。",[26,27,28],"blockquote",{},[14,29,30],{},"なんか1年後の目標株価の値が変になってる気がするんですけど、これ何のエラーですか？",[14,32,33],{},"Claude Code は、これを家族の口座の定期タスクが出す LINE 通知の「1年後目標」だと受け取り、計算の元データを調べた。\n返ってきた原因は「今朝の実行で目標株価（アナリスト予想）の取得が失敗し、目標株価なしで計算されたこと」だった。",[18,35,37],{"id":36},"_404-が空の予想として素通りしていた","404 が空の予想として素通りしていた",[14,39,40],{},"実行ログを見ると、朝7時11分の実行で、アナリスト予想を配る自前の GAS の API が HTTP 404 を返していた。\n取得関数は、失敗をログに1行書いたあと、空の予想を返して処理を続ける作りだった。",[42,43,48],"pre",{"className":44,"code":45,"language":46,"meta":47,"style":47},"language-js shiki shiki-themes vitesse-light vitesse-light","} catch (error) {\n  await appendFile(LOG_PATH, `... Analyst summary fetch failed: ...`);\n  return {};\n}\n","js","",[49,50,51,59,65,71],"code",{"__ignoreMap":47},[52,53,56],"span",{"class":54,"line":55},"line",1,[52,57,58],{},"} catch (error) {\n",[52,60,62],{"class":54,"line":61},2,[52,63,64],{},"  await appendFile(LOG_PATH, `... Analyst summary fetch failed: ...`);\n",[52,66,68],{"class":54,"line":67},3,[52,69,70],{},"  return {};\n",[52,72,74],{"class":54,"line":73},4,[52,75,76],{},"}\n",[14,78,79],{},"目標時価の計算では、目標株価が当たった銘柄だけをその目標株価で評価し、当たらない銘柄は時価のまま数える。\n予想が空なら、すべての銘柄が時価のまま数えられる。\n通知に載ったのは、「目標」の行に現在の時価がそのまま入った値だった。",[14,81,82],{},"処理はエラーで止まらず、それらしい数字が通知に出る。\n通知だけを見ても、取得に失敗したことはわからない。",[14,84,85],{},"GAS の 404 は、この日が初めてではない。\n修正のときにコードへ残したコメントによると、9月15日と9月18日にも一時的に 404 を返していた。",[18,87,89],{"id":88},"何を返事すればいいんですか","「何を返事すればいいんですか」",[14,91,92],{},"原因を聞いたあとも、Claude Code には日記本体の作業を進めさせていた。\n経過報告には、目標株価の件（通知の出し直しと再発防止）は返事をもらってから着手する、と書いてあった。\n次の報告にも「まだ返事待ちで手を付けていません」とある。\nただ、自分には何を返事すればいいのかが見えていなかった。",[26,94,95],{},[14,96,97],{},"これは何を返事すればいいんですか？",[14,99,100],{},"聞き返すと、決めてほしいことが2つに分けて出てきた。",[102,103,104,108],"ol",{},[105,106,107],"li",{},"今日の LINE 通知を、正しい値で出し直すか",[105,109,110],{},"再発防止の修正を入れるか",[14,112,113],{},"返事は1行で済んだ。",[26,115,116],{},[14,117,118],{},"1も出して、2は直してください。",[18,120,122],{"id":121},"取り直しは1回取れなければ目標行を出さない","取り直しは1回、取れなければ目標行を出さない",[14,124,125],{},"1つめの通知の出し直しは、この日のうちに済んだ。\n実行ログには同じ日の7時48分にもう一度実行した記録があり、こちらには予想の取得失敗が残っていない。",[14,127,128],{},"再発防止は、Claude Code に2段構えで入れてもらった。",[130,131,132,135],"ul",{},[105,133,134],{},"予想の取得に失敗したら、5秒おいて1回だけ取り直す",[105,136,137],{},"それでも取れず、目標株価が1銘柄も当たらなかったときは、目標時価そのものを出さない（通知に目標行が載らない）",[14,139,140],{},"2段目は、目標株価で計算できた金額が0なら null を返す小さな関数で判定する。",[42,142,144],{"className":44,"code":143,"language":46,"meta":47,"style":47},"export const targetValueOrNull = (target) =>\n  (target && target.coveredValueJpy > 0 ? target : null);\n",[49,145,146,151],{"__ignoreMap":47},[52,147,148],{"class":54,"line":55},[52,149,150],{},"export const targetValueOrNull = (target) =>\n",[52,152,153],{"class":54,"line":61},[52,154,155],{},"  (target && target.coveredValueJpy > 0 ? target : null);\n",[14,157,158],{},"複数の口座を合算した目標は、もともと1つでも欠けていれば出さない作りだった。\nそのため、新しい関数が返す null はそのまま合算にも伝わる。",[14,160,161],{},"テストには、予想が空の日は目標を出さないことと、合算も1つでも欠ければ出さないことを確かめる1件を足した。\n流すとテストが1件落ちたので、Claude Code に原因を見てもらってから直した。\nこれで目標株価の件は2つとも終わり、/make-diary（10/22 分）も最後まで回った。",[14,163,164,165,170],{},"目標株価まわりでは、9月19日にも",[166,167,169],"a",{"href":168},"/analyst-target-price-ticker-mismatch","一部の銘柄だけ目標株価が出なかった件","を直している。\nあのときは値が欠けた銘柄が見えていたが、今回は欠けたことが時価の数字に隠れていた。",[18,172,173],{"id":173},"学び",[130,175,176,179],{},[105,177,178],{},"取得に失敗した値を空のオブジェクトで素通りさせると、エラーではなく、それらしい数字になって通知に載る。入力が欠けた日は、値を出すより行ごと出さないほうが読み違えない。",[105,180,181],{},"「返事待ち」とだけ書かれても、何を決めるのかが並んでいなければ返事できない。番号つきの2択が出て、ようやく1行で答えられた。",[183,184,185],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":47,"searchDepth":61,"depth":61,"links":187},[188,189,190,191,192],{"id":20,"depth":61,"text":21},{"id":36,"depth":61,"text":37},{"id":88,"depth":61,"text":89},{"id":121,"depth":61,"text":122},{"id":173,"depth":61,"text":173},"dev",null,"家族の証券口座のポートフォリオ通知で「1年後目標」の値に違和感があった。朝の実行でアナリスト予想の取得が404で失敗し、目標株価なしで計算されていた。通知を出し直し、取り直し1回と目標行の非表示で再発を防いだ。","md",{},true,"/analyst-target-fetch-failure-line-notification","financial-data",false,"2026-10-23T00:00:00.000Z",{"title":5,"description":195},"make-diary","2026-10/2026-10-23/analyst-target-fetch-failure-line-notification",[207,208,209,210,211,212],"LINE通知","GAS","目標株価","リトライ","テスト","デバッグ","61PbKf-q_L7PrEnItVCOqkYWiHfpr0I9ATmylwYCH0M",[],[216,219,223,227,231],{"title":217,"path":168,"publishedAt":218},"韓国株だけ目標株価が出なかった原因は、ティッカーの取引所接尾辞だった","2026-09-19T00:00:00.000Z",{"title":220,"path":221,"publishedAt":222},"ポートフォリオ自動集計と証券会社の円換算額が合わない理由をウォン円レートから検算した","/portfolio-krwjpy-rate-gap-check","2026-09-23T00:00:00.000Z",{"title":224,"path":225,"publishedAt":226},"LINE通知の銘柄カードに「最高値比」を足し、リポジトリのコミットを整理した","/daily-chain-notification-card-and-repo-tidying","2026-09-04T00:00:00.000Z",{"title":228,"path":229,"publishedAt":230},"台湾 後工程・テスト4社の2026年9月 — 過去最高を更新したのはASEだけ、残る3社は前月比で小幅マイナス","/taiwan-test-osat-2026-09","2026-10-13T00:00:00.000Z",{"title":232,"path":233,"publishedAt":234},"DA Davidson はなぜ Micron の目標株価を3,000ドルに上げたのか：上げ幅は倍率の13倍→19倍で説明できる","/micron-da-davidson-3000-target","2026-10-08T00:00:00.000Z","https://log.eurekapu.com/og/blog/analyst-target-fetch-failure-line-notification.png?v=2026-10-23T00%3A00%3A00.000Z&title=LINE%E9%80%9A%E7%9F%A5%E3%81%AE%E3%80%8C1%E5%B9%B4%E5%BE%8C%E7%9B%AE%E6%A8%99%E3%80%8D%E3%81%8C%E3%81%8A%E3%81%8B%E3%81%97%E3%81%8B%E3%81%A3%E3%81%9F%E5%8E%9F%E5%9B%A0%E3%81%AF%E3%80%81%E7%9B%AE%E6%A8%99%E6%A0%AA%E4%BE%A1%E3%81%AE%E5%8F%96%E5%BE%97%E5%A4%B1%E6%95%97%E3%81%A0%E3%81%A3%E3%81%9F&author=Kei%20Komatsu&sig=253dbbc02603a1d1",1792796521347]