Skip to content

Metadata tab in Info window never populates — WPF DataGrid throws "ItemsControl is inconsistent with its items source" (Windows, 9.5.2) #18332

Description

@pwkwiatkowski

Describe the bug

In the Info window, the Metadata tab shows an indefinite progress indicator and the headers table stays empty. It never finishes, for any object I tried (CSS, PNG), on an S3 connection.

This is not a server or credentials problem. The debug log shows the HEAD request returning 200 OK and ReadMetadataWorker completing successfully with three metadata entries and no failure. The failure is entirely on the .NET side: a crash report is written with an InvalidOperationException from the HeadersGrid DataGrid. Details under Additional context.

To Reproduce

Steps to reproduce the behavior:

  1. Connect to an S3 bookmark (in my case an S3-compatible endpoint, Ceph RGW behind nginx).
  2. Select any object in the browser, e.g. css/styles.min.css.
  3. Open the Info window (Ctrl+I) and click the Metadata tab.
  4. The progress indicator spins indefinitely and no rows ever appear. A crash report appears in %APPDATA%\Cyberduck\CrashReporter\.

Expected behavior

The headers table lists the metadata returned by the HEAD request — in my case the three entries the worker actually returned: Cache-Control, Content-Encoding, Content-Type.

Screenshots

Attached: the Metadata tab with the stuck progress indicator and an empty headers table.

Desktop (please complete the following information):

  • OS: Windows 11 Pro 24H2, build 10.0.26100, x64, display language Polish
  • Version: Cyberduck 9.5.2.45323 (installer build from cyberduck.io, not Microsoft Store)
  • Protocol: S3 profile against an S3-compatible endpoint (Ceph RGW behind nginx)

Log Files

Attached: cyberduck-28-07-crash-window.log — debug log (Preferences → Connection → debug log) trimmed to the two minutes preceding the crash. The relevant sequence:

15:00:27,265  Run action WorkerBackgroundAction{worker=ReadMetadataWorker{...}} in background
15:00:27,379  http-outgoing-10 >> HEAD /css/styles.min.css HTTP/1.1
15:00:27,427  http-outgoing-10 << HTTP/1.1 200 OK
15:00:27,469  Cleanup with result {Cache-Control=public, max-age=60, Content-Encoding=gzip,
              Content-Type=text/css} and failure null
15:00:33,977  Run action WorkerBackgroundAction{worker=ReadAclWorker{...}}      (Permissions tab)
15:00:37,946  Cleanup with result [AllUsers:READ, ...] and failure null
15:00:41,324  Run action WorkerBackgroundAction{worker=VersionsWorker{...}}     (Versions tab)
15:01:50,216  WARN EditorFactory - No editor found for styles.min.css.map
              (the browser selection appears to have changed at this point)
15:01:52,904  Run action WorkerBackgroundAction{worker=VersionsWorker{...}}     (Versions tab again)
15:01:54,876  Run action WorkerBackgroundAction{worker=ReadAclWorker{...}}      (Permissions tab again)
15:02:02,471  Cleanup with result [AllUsers:READ, ...] and failure null
15:02:02,493  last line in the attached log
15:02:04      crash report file written (file mtime; the report itself only records 13:02 UTC,
              i.e. minute granularity)

Nothing is logged on the Java side after the successful cleanup — no exception, no timeout. Every Run action line present in the attached log is listed above. The CrashReporter directory held a single report for that session, written after the last of those tab switches.

Additional context

Also attached: crash-report-sanitized.txt. The exception is:

Type:    System.InvalidOperationException
Source:  PresentationFramework
Message: An ItemsControl is inconsistent with its items source.

Inner exception:
  the generator for control 'System.Windows.Controls.DataGrid Items.Count:0' with name
  'HeadersGrid' has received a sequence of CollectionChanged events that do not agree with
  the current state of the Items collection.
    Accumulated count 0 is different from actual count 3.

  One or more of the following sources may have raised the wrong events:
    System.Windows.Controls.ItemContainerGenerator
     System.Windows.Controls.ItemCollection
      System.Windows.Data.ListCollectionView
  *   DynamicData.Binding.ObservableCollectionExtended<
          Ch.Cyberduck.Core.Refresh.ViewModels.Info.MetadataViewModel+Entry>

Top of the stack: ItemContainerGenerator.Verify()VirtualizingStackPanel.MeasureChildDataGridRowsPresenter.MeasureOverride → … → HwndSource.Process_WM_SIZE.

The actual count of 3 matches exactly the three entries ReadMetadataWorker returned, so the collection was populated while the DataGrid never received consistent change notifications. This looks like the metadata collection being mutated off the WPF dispatcher thread — the worker callback runs on a background thread (background-* in the log) — leaving HeadersGrid in an inconsistent state.

The exception only surfaces on the next layout pass, which is why the timestamps differ: metadata was read at 15:00:27, and the crash report file is written at 15:02:04 — shortly after the last tab switch at 15:01:54,876, on what appears to be the layout pass following the ACL read that finished at 15:02:02,471. That also explains Process_WM_SIZE at the bottom of the stack rather than the point where the items were added.

Notes on the attachments:

  • The inner exception text in the crash report is in Polish, because WPF localises those messages. The block quoted above is my translation.

  • The crash report header reads Time: 13:02 (UTC) while the log uses local time (CEST, UTC+2). Both refer to the same moment, 15:02 local.

  • Both attachments have been sanitized:

    Hostnames, bucket names, credentials, signatures, IP addresses, ACL identities, the local machine name and the RGW operation id are replaced with placeholders (s3.example.com, example-bucket, AKIAEXAMPLEACCESSKEY, example-tenant, 192.0.2.10 / 192.0.2.20, EXAMPLE-PC, example-op-id). This includes the certificate DN fields, so O=Example Corp, CN=lb.internal.example.com and Example Corp Private Intermediate CA are placeholders too, not the real organisation or CA. Of the two addresses, 192.0.2.10:443 is the server and 192.0.2.20 the client. The bookmark UUID is zeroed.

    The debug log has also had all org.apache.http.wire lines removed. Those lines contained raw byte dumps of the request and response bodies; the responses were gzip-compressed, so text-level anonymisation did not reach inside them and they still contained unredacted identifiers. Removing them costs nothing here: all request and response headers remain in plain text under the org.apache.http.headers and transcript loggers, and the parsed response bodies are visible through XmlResponsesSaxParser and the worker results. Both attachments open with a header comment listing every modification, including what was deliberately left alone. The crash report additionally had the hardware fields (Manufacturer, Model, TotalPhysicalMemory, FreePhysicalMemory) removed, as they say nothing about a WPF layout bug.

    The ETag value was zeroed as well, since it is a digest of a publicly readable object; the weak-ETag prefix W/ and the length are preserved, because that prefix is what triggers the Checksum - Failure to detect algorithm warning. Everything else — timestamps, thread names, logger names, log levels, object paths, TLS parameters and header names — is unmodified. Note that because the wire lines were removed, line numbers in the attached log do not match those of a freshly generated one.

crash-report-sanitized.txt
cyberduck-28-07-crash-window.log
Image

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions